Trailing-Edge
-
PDP-10 Archives
-
klad_sources
-
klad.sources/mapsup.mac
There are no other files named mapsup.mac in the archive.
RELOC
SEARCH DEFINS,MONSYM
;Routines in this module used by the program
ENTRY DBEDIT,GETENT,PUTENT,MAKBAT,ENTOLD,ENTNEW
ENTRY LSTQ,LSTQO,BATDSB,MERGEB,PRGENT,CKENPT
INTERN ENT1,ENT2,ENT3,LBN
;These are located in the mainline
EXTERN BUF1A,VARFLG
;These are located in dfdxg1/dfrpm1
EXTERN BRANCH,IOWAIT,XFSTRT,UNITF,UNIT
;These are located in the rh20 support file
EXTERN CHSEL
;These are located in the general utility module
EXTERN TYPBIT,POCDEC,POCT,PSDN,RUNTMF,TSCAN,APRSN,QSTN
EXTERN RUNTME,NUMIN,POCDEF
;These are located in the common disk file
EXTERN ADCON,CWRWD,GENBAT,LBCE
;These are located in genvar module
EXTERN CYL1,SURF1,SECT1,INPUT
; **** Notes concerning mapout support in this program ****
;This program keeps track of data errors by disk address. each data error
;Will be logged in the data base along with some additional status info
;Needed by the program. the data base in this program has room for a total
;Of 400 errors (separate disk addresses).
;
;Each database entry consists of 3 words, the first 2 are exactly the
;Same as a 2 word bat block entry. the words are broken down like this:
;
;Word-1
;Bits 00-08 contain the number of bad blocks in a region - 1 (nbr)
;Bit 09 will be set if this block was detected on more than 1 rh20 (mul)
;Bits 10-17 contain (in unary), the drives where this block was located (pub)
;Bits 18-20 contain the logical rh where the address was first located (knm)
;Bit 21 always a 1, indicating a new style bat block
;Bits 22-35 contains the serial number of the apr (aprid)
;
;Word-2
;Bits 14-35 contain a logical block number of first block in region (lbn)
;
;Word-3
;(Bbu) bit 00 this bit being set will cause entry to go to bat blocks
;(Ebu) bit 01 this bit says operator forced bit zero to be set
;(Cbu) bit 02 this bit says operator forced bit zero to be reset
;(Bat) bit 03 this bit says entry was found in bat block on media
;(Pgm) bit 04 this bit says entry was found by the program
;(Opr) bit 05 this bit says entry was made by the operator
;(Pnt) bit 06 this bit says operator wants all errors printed from this address
;Bits 08-14 bits indicating what types of errors detected at this address
;(Hec) bits 18-26 number of times this address was found as a hard error
;(Heo) bit 16 indicates that the hard error counter has overflowed
;(Sec) bits 27-35 number of times this address was found as a soft error
;(Seo) bit 17 indicates that the soft error counter has overflowed
;
;The mapout routine allows the user 2 levels of commands. the top level
;Commands allow you to manipulate the data base in a global way. from
;The top level the user has the following commands available:
;
;Lsthrd - list all entries with bbu=1 (the 1st 61 of these go to bat blocks)
;Lstsft - list entries with bbu=1 (these don't go to the bat blocks)
;Lstall - list all entries
;Clrdb - clear the data base (all bad spot data is gone)
;Wrtbat - writes bat blocks with entries with bbu=1. (1st 61 only)
;Done - exit the mapout routine
;H - blurb of this list
;Editl - go to next command level "data base entry/edit using logical blocks)
;Editp - go to next command level "data base entry/edit using physical blocks)
;Listq - quick summary by lbn only (decimal)
;Listqo - quick summary by lbn only (octal)
;The following will be printed for each mapout entry. lines that start
;With an asterisk are printed only when they apply.
;
;Running mapout rh-xxx drive-x runtime (hh:mm:ss) xx:yy:zz
; Mapout entry: rh-xxx drive(s)-x multi-rh:yes aprid=xxxxx.
; Lbn=oooooo(ddddddd.) cyl=oooo(dddd.) surf=oo(dd.) sect=oo(dd.)
; Entry came from: bat pgm opr blocks in region=xxx.
; Hard errors detected=xxxx. soft errors detected=xxxx.
;* Errors detected: dck opi hcrc ech
;* Soft error counter has overflowed
;* Hard error counter has overflowed
; Entry will (not) be put in bat block (opr canceled update)
;* Errors from this address will be reported
; ----
;
;Editp and editl allow you to edit individual entries of the mapout data base
;The only difference is that in one case you select the entry by logical block
;And in the other you select the entry by physical address cyc, surf, sect.
;In entry edit mode you are really diddling a copy of the data base entry
;So there's no need to worry about destroying it. the edits only go back to
;The data base when a "done" ore "next" command are executed.
;
;The following commands are allowed while at "entry edit" level:
;
;List - list state of the current (edited) entry
;Mr - modify region (# of bad blocks in region)
;Hard - sets bbu=1, entry becomes hard error and will go to bat block
;Soft - sets bbu=0, entry becomes soft error and will not go to bat block
;Clrst - clear error status info bits 08-35 of 3rd word
;Pnt - allows further reporting of errors from this disk address
;Nopnt - inhibits further printing of errors from this disk address
;Clrent - clear this entry. this address no longer in data base
;Cancel - leave entry edit mode and don't update the data base
;Done - leave entry edit mode after updating the data base
;Next - update the data base and process another entry
;H - this message
;Dbedit -- mapout data base editor (top level)
;This routine is called from mapout when running in variable mode. the
;Following commands are supported here:
;
;Lsthrd - list all entries with bbu=1 (the 1st 61 of these go to bat blocks)
;Lstsft - list entries with bbu=0 (these don't go to the bat blocks)
;List - list all entries
;Listq - quick summary by lbn only (decimal)
;Listqo - quick summary by lbn only (octal)
;Clrdb - clear the data base (all bad spot data is gone)
;Wrtbat - writes bat blocks with entries with bbu=1. (1st 61 only)
;Done - exit the mapout routine
;H - this message
;Editl - go to next command level "data base entry/edit using logical blocks)
;Editp - go to next command level "data base entry/edit using physical blocks)
;
;The mapout data is located in the dsb area at offset "dbstrt" and is of
;Length "dbsize"
;
;Call seq:
; Go dbedit ;call this routine
; Rtn-1 ;one return....
DBEDIT: PUT 0 ;Save ac's
PUT 1
PUT 2
TEXTF [ASCIZ/
NOW EDITING DATA-BASE
/]
SKIPA ;Skip over error prompt
DBED0: TEXTF [ASCIZ/ ???/]
DBED1: TEXTF [ASCIZ/
DATA-BASE-EDIT CMD (OR H<CR>) - /]
TTSIXB ;Input a command in sixbit
JRST DBED0 ;Error return
JUMPE 0,DBED0 ;If ac0=0 we have an input error
MOVE 2,0 ;Get command to ac2
MOVEI 1,MCMD1 ;Get address of command name table
GO TSCAN ;Look up to check for legal command
JRST DBED0 ;Error. non implemented command
CAMN 2,[SIXBIT/DONE/] ;Is he done ?
JRST DBEDX ;Yes. exit
GO @MCMD1A(1) ;No. dispatch to proper command handler
JRST DBED1 ;And now go ask for the next command
DBEDX: GET 2 ;Restore ac's
GET 1
GET 0
RTN ;Exit
;Table of legal commands
MCMD1: SIXBIT /LSTHRD/ ;List if bbu=1
SIXBIT /LSTSFT/ ;List if bbu=0
SIXBIT /LIST/ ;List all entries
SIXBIT /LISTQ/ ;Summary by lbn only (decimal)
SIXBIT /LISTQO/ ;Summary by lbn only (octal)
SIXBIT /CLRDB/ ;Clear data base
SIXBIT /WRTBAT/ ;Write bat blocks now
SIXBIT /DONE/ ;Finished
SIXBIT /H/ ;Help message
SIXBIT /EDITL/ ;Edit in logical block mode
SIXBIT /EDITP/ ;Edit in physical block mode
Z ;End of table marker
;Table pointing to service routine for each command
MCMD1A: LSTHRD ;List if bbu=1
LSTSFT ;List if bbu=0
LSTALL ;List all entries
LSTQ ;Quick summary by lbn (decimal)
LSTQO ;Quick summary by lbn (octal)
CLRDB ;Clears the data base
WRTBAT ;Creates and writes new bat blocks
[RTN] ;For done cmd ... never gets executed
DBHELP ;Prints the help message for dbedit
EDITL ;Edit entry in logical mode
EDITP ;Edit entry in physical mode
Z ;End of table mark
; Dbhelp -- subroutine to print help message for dbedit routine
;
; Call seq:
; Go dbhelp ;the call
; Rtn-1 ;the return
DBHELP: TEXTF [ASCIZ?
LSTHRD - LIST ENTRIES THAT WILL GO TO BAT BLOCKS (1ST 61 GO TO BAT)
LSTSFT - LIST ENTRIES THAT WILL NOT GO TO THE BAT BLOCKS
LIST - LIST ALL ENTRIES IN DATA BASE
LISTQ - SUMMARY AND QUICK LIST BY DISK ADDR (DECIMAL)
LISTQO - SUMMARY AND QUICK LIST BY DISK ADDR (OCTAL)?]
TEXTF [ASCIZ?
CLRDB - CLEAR THE DATA BASE (ALL BAD SPOT DATA IS LOST)
WRTBAT - WRITES BAT BLOCKS NOW
DONE - EXIT THE MAPOUT ROUTINE
EDITL - EDIT ENTRIES BY LOGICAL BLOCK NUMBERS
EDITP - EDIT ENTRIES IN PHYSICAL ADDRESS MODE
H - BLURB OF THIS LIST
?]
RTN ;Exit after prnting the text ...
;Subroutine to write bat blocks with all (up to 61) data base entries
;Whose bbu=1 ...
;Buf1a is used as the write buffer
;
; Call seq:
; Go wrtbat ;call the routine
; Rtn ;+1 always
WRTBAT: PUT 1 ;Save ac
MOVE 1,BUF1A ;Get buffer addr
GO MAKBAT ;Do it now
GET 1 ;Restore ac
RTN ;Exit
; Subroutines to list data base entries
;There are 3 entry points into 1 routine to list hard, soft, all entries
;
; Call seq:
; Go lstxxx ;xxx is either hrd, sft,all
; Rtn ;rtn-1 always
LSTALL: PUT 4 ;Save ac4
MOVE 4,[JFCL] ;A no-op for later
JRST LSTCMN ;To common code
LSTHRD: PUT 4 ;Save ac4
MOVE 4,[TLNE 2,400000] ;Skips if bbu=0
JRST LSTCMN ;To common code
LSTSFT: PUT 4 ;Save ac4
MOVE 4,[TLNN 2,400000] ;Skips if bbu=1
JRST LSTCMN ;To common code
LSTCMN: PUT 2 ;Save rest of ac's
PUT 1
MOVEI 1,DBSTRT(DSW) ;Keep our pointer in ac1
LLOOP: MOVE 2,(1) ;Get a data base entry
JUMPE 2,LNXT ;Skip if entry is zero
MOVE 2,2(1) ;Get entry word-3
XCT 4 ;Does correct test/skip instruction
GO ENTPNT ;Print entry. ac1 points to it
LNXT: ADDI 1,3 ;Point to next possible entry
CAIGE 1,DBEND(DSW) ;Are we done ?
JRST LLOOP ;No.
GET 1 ;Yes. restore ac's
GET 2
GET 4
RTN ;And exit
;Subroutine to clear entire data base
;This requires confirmation (only) if you're in variable mode
;All mapout data is then gone ....
;This also clears the hard and soft spot counters in the dsb area
; Sspots=0 and hspots=0
;
; Call seq:
; Go clrdb ;call the routine
; Rtn-1 ;+1 always
CLRDB: PUT 1 ;Save an ac
SKIPN VARFLG ;In variable mode ?
JRST CLRDBG ;No... no confirmation necessary
TEXTF [ASCIZ/
THIS COMMAND CAUSES ALL MAPOUT AND BAT BLOCK INFO TO BE DELETED FOR
THIS DRIVE. DO YOU WISH TO PROCEED /]
GO QSTN ;Ask (y or n)
JRST .-1 ;Timeout
JRST CLRDBX ;Answer was no ...
CLRDBG: MOVNI 1,DBSIZE-1 ;-Count
HRL 1,1 ;-Cnt to left side of ac
HRRI 1,DBSTRT(DSW) ;-Cnt,,ptr
SETZM (1) ;Clear a cell
AOBJN 1,.-1 ;Loop till done
SETZM HSPOTS(DSW) ;Clear hard spot counter
SETZM SSPOTS(DSW) ;Clears soft spots counter
CLRDBX: GET 1 ;Restore the ac
RTN ;And exit
;Lstq - lstqo -- routine to give quick summary of data base
;This routine lists the lbns of the bad spots, indicates whether they
;Are hard (will go to bat blocks) or soft (will not go to bat blocks)
;And also lists the number of times each address (spot) was found to
;Be hard or soft
;
;Threre are 2 entry points. lstq prints in decimal and lstqo
;Prints in octal ....
;
;Call seq:
; Go lstq (or lstqo) ;the call
; Rtn1 ;+1 always
;Here's the entry for decimal printer
LSTQ: PUT 4 ;Save ac4
SETOM 4 ;Flag tells how we're printing
JRST LSTQC ;To common code
;Here's the entry for octal printer
LSTQO: PUT 4 ;Save ac4
SETZM 4 ;Flag tessl how we're printin
JRST LSTQC ;To common code
;Here's the common code
LSTQC: PUT 0 ;Save he other ac's
PUT 1
PUT 2
PUT 3
TEXT [ASCIZ/
MAPOUT-DATA-BASE-SUMMARY: /]
GO RUNTME ;Print runtime
PCRL
GO UNIT ;Identify rh, drive etc...
TEXT [ASCIZ?
THERE ARE ?]
MOVE 0,HSPOTS(DSW) ;Get hard spot count
GO PSDN ;Print
TEXT [ASCIZ/ HARD REGIONS AND /]
MOVE 0,SSPOTS(DSW) ;Get soft spot count
GO PSDN ;Print
TEXT [ASCIZ/ SOFT REGIONS KNOWN TO PROGRAM
/]
;Now list them if there are any in either octal or decimal
MOVE 0,HSPOTS(DSW) ;Get hards
ADD 0,SSPOTS(DSW) ;Include softs
JUMPE 0,LSTQX ;Exit if there is nothing to report
TEXT [ASCIZ/STARTING ADDRESSES OF THE REGIONS ARE:
/]
TEXT [ASCIZ/ LBN CYL SURF SECT #-HARD #-SOFT
--- --- ---- ---- ------ ------
/]
MOVEI 3,DBSTRT(DSW) ;Set up pointer into data base
LSTQF: MOVE 2,(3) ;Get wd-1 of entry
JUMPE 2,LSTQN ;Non-entry if wd-1 is zero
LDB 0,[POINT 27,1(3),35] ;Ok. lbn goes to ac0
MOVE 2,2(3) ;Get entry word-3 (status)
MOVEI 1,[ASCIZ/* HARD /] ;Assume its hard
TLNN 2,400000 ;Is bbu=1
MOVEI 1,[ASCIZ/ SOFT /] ;No. change message
TEXT (1) ;Print message pointed to by ac1
MOVE 1,[GO PSDN] ;Assume we'll be doing decimal
SKIPN 4 ;If ac4=0 we're doing octal ..
MOVE 1,[GO POCT] ;Modify our choice of routines
XCT 1 ;To proper print routine
TEXT [ASCIZ/ /] ;Tab over
MOVE 1,0 ;Get lbn to ac1
SETZM 2 ;Clear ac2
GO ADCON ;Convert to physical address
HLRZ 0,2 ;Get cyl #
MOVE 1,[GO PSDN] ;Assume we'll be doing decimal
SKIPN 4 ;If ac4=0 we're doing octal ..
MOVE 1,[GO POCT] ;Modify our choice of routines
XCT 1 ;To proper print routine
TEXT [ASCIZ/ /] ;Tab over
LDB 0,[POINT 8,2,27] ;Get the surface number
MOVE 1,[GO PSDN] ;Assume we'll be doing decimal
SKIPN 4 ;If ac4=0 we're doing octal ..
MOVE 1,[GO POCT] ;Modify our choice of routines
XCT 1 ;To proper print routine
TEXT [ASCIZ/ /] ;Tab over
LDB 0,[POINT 8,2,35] ;Get the sector
MOVE 1,[GO PSDN] ;Assume we'll be doing decimal
SKIPN 4 ;If ac4=0 we're doing octal ..
MOVE 1,[GO POCT] ;Modify our choice of routines
XCT 1 ;To proper print routine
TEXT [ASCIZ/ /] ;Tab
MOVE 1,2(3) ;Get the 3rd wd
TLNN 1,(1B16) ;Is heo set ?
JRST .+3 ;No. print normal
TEXT [ASCIZ/OVRFLO/]
JRST LSTQF1 ;Now do soft
LDB 0,[POINT 9,2(3),26] ; No overflo. get hard count
GO PSDN ;Print it
LSTQF1: TEXT [ASCIZ/ /] ;Tab
TLNN 1,(1B17) ;Is seo set ?
JRST .+3 ;No. print normal
TEXT [ASCIZ/OVRFLO/]
JRST LSTQF2 ;Bac to common code
LDB 0,[POINT 9,2(3),35] ;Get soft error count
GO PSDN ;Print it
LSTQF2: PCRL ;Advance to next line
LSTQN: ADDI 3,3 ;Point to next entry
CAIGE 3,DBEND(DSW) ;Are we at the end ?
JRST LSTQF ;No. process next entry
LSTQX: GET 3 ;Yes. restore ac's
GET 2
GET 1
GET 0
GET 4
RTN ;And exit
;Editp - editl -- mapout data base entry editor (2nd level cmds)
;This routine allows you to edit specific entries in the mapout data base. the
;Data base is located in the dsb area at offset "dbstrt" and is of size "dbsize".
;
;Editp and editl allow you to edit individual entries of the mapout data base
;The only difference is that in one case you select the entry by logical block
;And in the other you select the entry by physical address cyc, surf, sect.
;In entry edit mode you are really diddling a copy of the data base entry
;So there's no need to worry about destroying it. the edits only go back to
;The data base when a "done" ore "next" command are executed.
;
;The following commands are allowed while at "entry edit" level:
;
;List - list state of the current (edited) entry
;Mr - modify region (# of bad blocks in region)
;Hard - sets bbu=1, entry becomes hard error and will go to bat block
;Soft - sets bbu=0, entry becomes soft error and will not go to bat block
;Clrst - clear error status info bits 08-35 of 3rd word
;Pnt - allows further reporting of errors from this disk address
;Nopnt - inhibits further printing of errors from this disk address
;Clrent - clear this entry. this address no longer in data base
;Cancel - leave entry edit mode and don't update the data base
;Done - leave entry edit mode after updating the data base
;Next - update the data base and process another entry
;
;Call seq:
; Go xxxxx ;where xxxxx is editp or editl
; Rtn-1 ;always returns here
;Here is the edit entry for logical mode
EDITL: TEXTF [ASCIZ/
NOW EDITING INDIVIDUAL DATA-BASE-ENTRIES
/]
PUT 0 ;Save ac's
PUT 1
PUT 2
SETZM EDFLG ;Flag indicates logical block mode
EL0: GO GETLBN ;Input lbn (entire disk is legal)
MOVEM 0,LBN ;Save in ent for the future
JRST EPLCOM ;Go to common code
;Here is the edit entry for physical mode
EDITP: TEXTF [ASCIZ/
NOW EDITING INDIVIDUAL DATA-BASE-ENTRIES
/]
PUT 0 ;Save ac's
PUT 1
PUT 2
SETOM EDFLG ;Flag indicates physical address mode
EP0: MOVEI 1,CYL1 ;Want to input cyl1
SETZM 2 ;No restrictions
GO INPUT ;Do tty input
MOVEI 1,SURF1 ;Want to input surf1
SETZM 2 ;No restrictions
GO INPUT ;Do tty input
MOVEI 1,SECT1 ;Want to input sect1
SETZM 2 ;No restrictions
GO INPUT ;Do tty input
HRRZ 2,SURF1 ;Ac2/ 0,,surf1
LSH 2,^D8 ;Ac2/ 0,,surf1,0
IOR 2,SECT1 ;Ac2/ 0,,surf1,sect1
HRL 2,CYL1 ;Ac2/ cyl1,,surf1,sect1
SETOM 1 ;Says convert physical to logical
GO ADCON ;Do the conversion
MOVEM 1,LBN ;Save the lbn
TEXTF [ASCIZ/LBN = /]
MOVE 0,LBN ;Get logical block number
GO POCDEF ;Print in octal and decimal
PCRL ;A crlf
JRST EPLCOM
;From here on we have common edit code ...
EPLCOM: MOVE 1,LBN ;Get logical block number
SETZM 2 ;Clear ac2 ..
GO GETENT ;Look the entry up in our data base
JRST EDNEW ;+1 New entry.. ac2=0
JRST EDOLD ;+2 Old entry.. ac2=ptr into data base
EDNEW: TEXTF [ASCIZ/CREATING A NEW ENTRY/]
MOVEI 2,ENT1 ;Get pointer to 3 wd edit buffer
GO ENTNEW ;Create a new entry in edit buffer
JRST SETOPR ;Go set operator selected bit
EDOLD: TEXTF [ASCIZ/MODIFYING AN EXISTING ENTRY/]
MOVEI 1,ENT1 ;Pointer to 3 wd edit buffer
GO ENTOLD ;Fetch and update existing entry
SETOPR: MOVSI 1,(1B5) ;Sets bit-5
IORM 1,ENT3 ;Sets opr diddled this entry status bit
JRST EDCMD ;Go handle commands
;This code processes entry level edit comands from operator. the data has
;Been moved from the data base (or newly created) in the edit buffer at
;Ent1,ent2,ent3. the current logical block number is stored in lbn.
EDCMDE: TEXTF [ASCIZ/???/]
EDCMD: TEXTF [ASCIZ/
ENTRY-EDIT CMD (OR H<CR>) - /]
TTSIXB ;Get a command in sixbit
JRST EDCMDE ;Error on input
JUMPE 0,EDCMDE ;Error if ac0 = 0
MOVEI 1,MCMD2 ;Pointer to command table
MOVE 2,0 ;Get command to ac2
GO TSCAN ;Do a table lookup
JRST EDCMDE ;Error ... no such command
JFCL ;Ok. ac1 is an index. ac2 holds command
;Time to parse for special cases
CAME 0,[SIXBIT/CLRENT/] ;Clear entry ?
JRST EDDN ;No
SETZM ENT1 ;Yes. zero buffer
SETZM ENT2
SETZM ENT3
JRST UDNOW ;And update now
EDDN: CAME 0,[SIXBIT/DONE/] ;Finished entry edits ?
JRST EDCAN ;No
UDNOW: MOVE 1,LBN ;Get logical block number
MOVEI 2,ENT1 ;Pointer to edit buffer
GO PUTENT ;Put the entry away
JFCL ;+1 Data base is full
JRST EDEX ;+2 Ok.... exit
EDCAN: CAMN 0,[SIXBIT/CANCEL/] ;Abort edit commands ?
JRST EDEX ;Yes
CAME 0,[SIXBIT/NEXT/] ;Go onto next ?
JRST EDDISP ;No... process remainder of commands
MOVE 1,LBN ;Get logical block
MOVEI 2,ENT1 ;Pointer to edit buffer
GO PUTENT ;Update current entry
JFCL ;+1 Data base full
SKIPN EDFLG ;+2 Ok ... branch according to mode
JRST EL0 ;In logical edit mode
JRST EP0 ;In physical edit mode
EDDISP: GO @MCMD2A(1) ;Dispatch according to command
JRST EDCMD ;And process the next command
EDEX: TEXTF [ASCIZ/NOW EDITING DATA-BASE
/]
GET 2 ;Restore ac's
GET 1
GET 0
RTN ;And exit
;Command table for entry level editor
MCMD2: SIXBIT /LIST/ ;List entry
SIXBIT /MR/ ;Modify region
SIXBIT /HARD/ ;Make a hard error
SIXBIT /SOFT/ ;Make a soft error
SIXBIT /CLRST/ ;Clear status
SIXBIT /PNT/ ;Enable print all
SIXBIT /NOPNT/ ;Inhibit print
SIXBIT /CLRENT/ ;Delete this entry
SIXBIT /CANCEL/ ;Cancel this edit session
SIXBIT /DONE/ ;Finished edits
SIXBIT /NEXT/ ;Move on to next entry
SIXBIT /H/ ;Help
Z ;End of table marker
;Pointer to command service routines
MCMD2A: ENTLST ;List entry
ENTMR ;Modify region
ENTHRD ;Make a hard error
ENTSFT ;Make a soft error
ENTCST ;Clear status/error info
ENTPT ;Set the pnt bit
ENTNPT ;Clear the pnt bit
[RTN] ;Clear handled elsewhere
[RTN] ;Cancel handled elsewhere
[RTN] ;Done is handled elsewhere
[RTN] ;Next is handled elsewhere
EDHLP ;Help command
Z ;End of table marker
;Here is a small storage area needed by edit routne
LBN: Z ;Lbn goes here
ENT1: Z ;Entry word-1 goes here
ENT2: Z ;Entry word-2 goes here
ENT3: Z ;Entry word-3 goes here
EDFLG: Z ;Edit mode flag. 0=logical, -1=physical
;Subroutine to input the logical block number (lbn)
;The limits are 0 through however many blocks are on the selected drive
;
; Call seq
; Go getlbn ;the call
; Rtn ;+1 always with lbn in ac0
GETLBN: JRST LBNIN ;Skip over input error code
LBNER: TEXTF [ASCIZ/** -- INPUT ERROR FOR "LBN"./]
TEXTF [ASCIZ/ THE FOLLOWING IS ALLOWED:
0 THRU /]
MOVE 0,LBCE(X1) ;Gets last block on disk
GO POCDEF ;Print it
PCRLF
JRST LBNIN ;Retry ..
LBNIN: TEXTF [ASCIZ/LOGICAL BLOCK (LBN) - /]
TTICNV ;Input a convertable number
JRST LBNER ;Error or timeout
CAIL 0,0 ;Range test
CAMLE 0,LBCE(X1)
JRST LBNER ;Out of range
RTN ;Ok. exit with number in ac0
;Routine allows operator to modify region of entry.
;Data is in ent1, ent2, ent3. up to 512. blocks in region is legal.
;
; Call seq
; Go entmr ;call the routine
; Rtn ;region is updated per operator request
ENTMR: PUT 0 ;Save the ac
SKIPA ;Skip error message
MRER: TEXTF [ASCIZ/???
/]
TEXTF [ASCIZ/SIZE OF REGION (1-512.) - /]
MOVE 0,[1,,^D512] ;Sets up the limits
GO NUMIN ;Input a number
JRST .-2 ;Timeout
JRST MRER ;Input error
SUBI 0,1 ;Ok. adjust because nbb=n-1
DPB 0,[POINT 9,ENT1,8] ;Updates the region
GET 0 ;Restore the ac
RTN ;And exit
;Edhlp -- subroutine to print help msg in entry level editor
;
; Call seq:
; Go edhlp ;call the routine
; Rtn-1 ;rtn+1 always
EDHLP: TEXTF [ASCIZ?
LIST - LIST STATE OF THE CURRENT (EDITED) ENTRY
MR - MODIFY REGION (# OF BAD BLOCKS IN REGION)
HARD - ENTRY BECOMES HARD ERROR AND WILL GO TO BAT BLOCK
SOFT - ENTRY BECOMES SOFT ERROR AND WILL NOT GO TO BAT BLOCK
CLRST - CLEAR ERROR STATUS AND COUNTERS ?]
TEXTF [ASCIZ?
PNT - ALLOWS FURTHER REPORTING OF ERRORS FROM THIS DISK ADDRESS
NOPNT - INHIBITS FURTHER PRINTING OF ERRORS FROM THIS DISK ADDRESS
CLRENT - DELETE THIS ENTRY FROM THE DATA BASE (IMMEDIATELY)
CANCEL - LEAVE ENTRY EDIT MODE (IMMEDIATELY) AND DON'T UPDATE THE DATA BASE
DONE - LEAVE ENTRY EDIT MODE AFTER UPDATING THE DATA BASE
NEXT - UPDATE THE DATA BASE AND PROCESS ANOTHER ENTRY
H - THIS MESSAGE
?]
RTN ;And exit
;Subroutine to list state of current edited entry
;The data is at location ent1, ent2, ent3 (the edit buffer)
;
; Call seq:
; Go entlst ;the call
; Rtn ;+1
ENTLST: PUT 1 ;Save the ac
MOVEI 1,ENT1 ;Pointer to edit buffer
GO ENTPNT ;Call the printer
GET 1 ;Restore the ac
RTN ;Exit
;Subroutine allows operator to declare the entry a hard error
;Data is in ent1, ent2, ent3. sets: bbu=1 ebu=1 cbu=0
;
; Call seq
; Go enthrd ;call the routine
; Rtn ;+1 always
ENTHRD: PUT 1 ;Save ac1
MOVE 1,ENT3 ;Get entry
TLO 1,600000 ;Bbu=1 ebu=1
TLZ 1,100000 ;Cbu=0
MOVEM 1,ENT3 ;Save entry
GET 1 ;Restore ac
RTN ;Exit
;Subroutine allows operator to declare the entry a soft error
;Data is in ent1, ent2, ent3. sets: bbu=0 ebu=0 cbu=1
;
; Call seq
; Go entsft ;call the routine
; Rtn :+1 always
ENTSFT: PUT 1 ;Save ac1
MOVE 1,ENT3 ;Get an entry
TLZ 1,600000 ;Bbu=0 ebu=0
TLO 1,100000 ;Cbu=1
MOVEM 1,ENT3 ;Save entry
GET 1 ;Restore ac
RTN ;Exit
;Subroutine to clear status information for entry
;Data is in ent1, ent2, ent3. clears bits 08-35 of entry word #3
;
; Call seq
; Go entcst ;the call
; Rtn ;+1 always
ENTCST: PUT 1 ;Save ac
SETZM 1 ;Clear ac
DPB 1,[POINT 28,ENT3,35] ;Clear the status information
GET 1 ;Restore the ac
RTN ;And exit
;Subroutine causes pnt=1.
;Data is in ent1, ent2, ent3
;
; Call seq
; Go entpt ;the call
; Rtn ;+1 always
ENTPT: PUT 1 ;Save ac1
MOVE 1,ENT3 ;Fetch entry
TLO 1,004000 ;Pnt=1
MOVEM 1,ENT3 ;Save entry
GET 1 ;Restore the ac
RTN ;Exit
;Subroutine causes pnt=0.
;Data is in ent1, ent2, ent3
;
; Call seq
; Go entnpt ;the call
; Rtn ;+1 always
ENTNPT: PUT 1 ;Save ac1
MOVE 1,ENT3 ;Fetch entry
TLZ 1,004000 ;Pnt=0
MOVEM 1,ENT3 ;Save the entry
GET 1 ;Restore the ac
RTN ;Exit
;Entnew -- routine to start processing a new data base entry
;The following functions are performed here:
;1. The entry is initialzed to 0
;2. The lbn is plugged into entry word-2
;3. Word-1 is completely initialized (aprid, pub, knm, etc)
;
;Call seq:
; Move 1,arg1 ;ac1 contains lbn
; Move 2,arg2 ;ac2 points to 3 wd buffer where entry goes
; Go entnew ;call the routine
; Rtn-1 ;a valid looking entry is in your buffer
ENTNEW: PUT 1 ;Save ac's
PUT 2
SETZM 0(2) ;Clears 3 wds of entry
SETZM 1(2)
SETZM 2(2)
MOVEM 1,1(2) ;Puts the lbn in the entry
GO APRSN ;Get serial number of the cpu to ac1
TRO 1,1B21 ;Set bit-21 at the same time
DPB 1,[POINT 15,(2),35] ;Stuff into first entry word
GO CHSEL ;Get logical chan # to ac1
DPB 1,[POINT 3,(2),20] ;Stuff into first entry word (knm)
MOVSI 1,1 ;1 Goes to bit 17
LSH 1,(DRIVE) ;Shift in unary to the left
IORM 1,(2) ;Put into he first word of the entry
GET 2 ;Restor ac's
GET 1
RTN ;And exit
;Entold -- routine to start processing existing entry
;This routne begins processing an existing entry after moving it to
;Your buffer from the data base:
;1. It updates entry word-1 only. in particular its job is to plug
; In the new drive number and decide if the mul bit should be set.
;
;Call seq:
; Move 1,arg1 ;ac1 holds a pointer to your edit buffer
; Move 2,arg2 ;ac2 holds a pointer to entry in the data base
; Go entold ;call the routine
; Rtn-1 ;your buffer now hold partially updated entry
ENTOLD: PUT 0 ;Save ac's
PUT 1
PUT 2
EXCH 2,1 ;Ac1/ptr to data base, ac2/ptr to your buffer
MOVE 0,0(1) ;Xfer 1st wd
MOVEM 0,0(2)
MOVE 0,1(1) ;Xfer second wd
MOVEM 0,1(2)
MOVE 0,2(1) ;Xfer third word
MOVEM 0,2(2)
GO APRSN ;Get serial number of cpu to ac1
ANDI 1,3777 ;Save 14 bits
MOVE 0,(2) ;Get first entry word
ANDI 0,3777 ;Save 14 bits
CAME 0,1 ;Is aprid=sn of cpu ?
JRST SETMUL ;No. set multi-rh bit in entry word-1
GO CHSEL ;Yes. get rh chan # to ac1
LDB 0,[POINT 3,(2),20] ;Get knm from entry word-1
CAMN 0,1 ;Is chan # = knm ?
JRST SETDRV ;Yes. no need to set mul bit
SETMUL: MOVSI 1,(1B9) ;Get the mul bit set
IORM 1,(2) ;Now ...
SETDRV: MOVSI 1,1 ;A 1 to bit 17
LSH 1,(DRIVE) ;Shift in unary to left
IORM 1,(2) ;Entry word-1 pub is now updated
GET 2 ;Restore ac's
GET 1
GET 0
RTN ;And exit
;Entpnt -- subroutine to print mapout data base entry
;This routine prints a breakdown of the contents of a mapout entry.
;
;Call seq:
; Move 1,arg1 ;pointer to first word of the entry
; Go entpnt ;call the routine
; Rtn-1 ;the return....
;
;The following will be printed for each mapout entry. lines that start
;With an asterisk are printed only when they apply.
;
;Running mapout rh-xxx drive-x runtime (hh:mm:ss) xx:yy:zz
; Mapout entry: rh-xxx drive(s)-x multi-rh:yes aprid=xxxxx.
; Lbn=oooooo(ddddddd.) cyl=oooo(dddd.) surf=oo(dd.) sect=oo(dd.)
; Entry came from: bat pgm opr blocks in region=xxx.
; Hard errors detected=xxxx. soft errors detected=xxxx.
;* Errors detected: dck ech hcrc dte opi etc
;* Soft error counter has overflowed
;* Hard error counter has overflowed
; Entry will (not) be put in bat block (opr canceled update)
; Errors from this address will (not) be reported
; ----
ENTPNT: PUT 0 ;Save the ac's
PUT 1
PUT 2
PUT 3
MOVE 3,1 ;We'll maintain our pntr in ac3
TEXT [ASCIZ/RUNNING-MAPOUT /]
GO RUNTME ;Program runtime
PCRL
GO UNIT ;Identify rh, drive, etc....
;Print the first line
TEXT [ASCIZ/
MAPOUT ENTRY: CHAN(RH)-/]
LDB 0,[POINT 3,(3),20] ;Get controller #
GO POCT
TEXT [ASCIZ/ ON DRIVE(S) /]
MOVE 1,(3) ;Get data
MOVEI 2,DVTB ;Get a table pointer
GO TYPBIT ;Identify drives
TEXT [ASCIZ/ MULTI-RH:/]
LDB 0,[POINT 1,(3),9] ;Get multi-rh bit
JUMPE 0,.+3 ;Is it set ?
TEXT [ASCIZ/YES/] ;Yes, say so.
SKIPA
TEXT [ASCIZ/NO/] ;It's not set
TEXT [ASCIZ/ APRID=/]
LDB 0,[POINT 14,(3),35] ;Get aprid field
GO PSDN
;Print the second line
TEXT [ASCIZ/
LBN=/]
LDB 0,[POINT 27,1(3),35] ;Get lbn
GO POCDEC
TEXT [ASCIZ/ CYL=/]
LDB 1,[POINT 27,1(3),35] ;Get lbn again
GO ADCON ;Convert to a disk address
HLRZ 0,2 ;Get cyl #
GO POCDEC
TEXT [ASCIZ/ SURF=/]
LDB 0,[POINT 8,2,27];Get surf #
GO POCDEC
TEXT [ASCIZ/ SECT=/]
LDB 0,[POINT 8,2,35];Get rec #
GO POCDEC
;Print the third line
TEXT [ASCIZ/
ENTRY CAME FROM: /]
MOVE 1,2(3) ;Get 3rd entry
MOVEI 2,WHOTB ;Get pointer to table
GO TYPBIT ;Tells where entry was found
TEXT [ASCIZ/ BLOCKS IN REGION=/]
LDB 0,[POINT 9,(3),8] ;Get the nbb field
AOS 0 ;Add 1 because its stored as n-1
GO PSDN
;Print the fourth line
TEXT [ASCIZ/
HARD ERRORS DETECTED=/]
LDB 0,[POINT 9,2(3),26] ;Get hard err count
GO PSDN
TEXT [ASCIZ/ SOFT ERRORS DETECTED=/]
LDB 0,[POINT 9,2(3),35] ;Get soft err count
GO PSDN
;Print the rest of the lines as necessary
MOVE 0,2(3) ;Get 3rd word of entry to ac0
TLNN 0,1770 ;Are any drive particular err bits set ?
JRST ENTPT1 ;No
TEXT [ASCIZ/
ERROR TYPE(S) DETECTED: /]
MOVE 1,0 ;Get data to ac1
MOVE 2,TBPTR(X1) ;Get table pointer to ac2
GO TYPBIT ;Interpret error bits 08-14
;Now check the overflow bits
ENTPT1: TLNE 0,(1B17) ;Has the soft err counter overflowed ?
TEXT [ASCIZ/
SOFT ERROR COUNTER HAS OVERFLOWED/] ;Yes
TLNE 0,(1B16) ;Has the hard err counter overflowed ?
TEXT [ASCIZ/
HARD ERROR COUNTER HAS OVERFLOWED/] ;Yes
;Tell him whether or not bbu is set
TEXT [ASCIZ/
ENTRY WILL/]
TLNN 0,(1B0) ;Is bbu set ?
TEXT [ASCIZ/ NOT/] ;No
TEXT [ASCIZ/ BE PUT IN BAT BLOCK/]
TLNE 0,(1B2) ;Is cbu set ?
TEXT [ASCIZ/ (OPR CANCELED UPDATE)/]
TLNE 0,(1B1) ;Is ebu set ?
TEXT [ASCIZ/ (OPR REQUESTED UPDATE)/]
;Check the pnt bit
TEXT [ASCIZ/
FURTHER ERRORS FROM THIS ADDRESS WILL/]
TLNN 0,(1B6) ;Is pnt bit set ?
TEXT [ASCIZ/ NOT/] ;No
TEXT [ASCIZ/ BE REPORTED/]
;Done at last
TEXT [ASCIZ/
----
/]
ENTPTX: GET 3 ;Restore the ac's
GET 2
GET 1
GET 0
RTN ;And exit
;Table defines bits where entry was found
WHOTB: 070000,,000000 ;These bits may be set
000000,,000000 ;These may never be set
SIXBIT /BAT/ ;Came from bat block
SIXBIT /PGM/ ;Came from program
SIXBIT /OPR/ ;Came from operator
;Pointers to error tables for various drives
TBPTR: ENER1 ;Rp04
ENER1 ;Rp06
ENER1 ;Rp07 (300 mb)
ENER1 ;Rp07 (600 mb)
ENER1 ;Rm03
ENER1 ;Rp06+
ENER1 ;Rp20 (tops10)
ENER1 ;Rp20 (tops20)
;Error translator table used by typbit
ENER1: 001770,,000000 ;Defines bits that may be set
000000,,000000 ;Defines bits that may never be set
SIXBIT /DCK/ ;A data check
SIXBIT /ECH/ ;Uncorrectable ecc error
SIXBIT /HCRC/ ;Header crc error
SIXBIT /HCE/ ;Header compare error
SIXBIT /DTE/ ;Drive timing error
SIXBIT /OPI/ ;Operation incomplete
SIXBIT / / ;Spare bit for now
;Translates unary field "pub" to text
DVTB: 000377,,000000 ;These may be set
000000,,000000 ;These may never be set
SIXBIT /7/
SIXBIT /6/
SIXBIT /5/
SIXBIT /4/
SIXBIT /3/
SIXBIT /2/
SIXBIT /1/
SIXBIT /0/
;Getent -- searches bat data base for an entry
;This routine will search the currently selected drive's
;Bat data base for an entry with the logical block
;Number contained in ac1.
;
;Calling seq:
; Move ac1, arg1 ;arg1 contains lbn
; Go getent ;search data base
; Rtn-1 ;no such entry in data base
; Rtn-2 ;found it. pointer in ac2.
GETENT: PUT 0 ;Save ac's
PUT 2
MOVEI 2,DBSTRT(DSW) ;Get a pointer to data base
GETNT1: LDB 0,[POINT 14,(2),35] ;Get aprid field of current entry
JUMPE 0,GETNTX ;Have we reached an empty entry ?
LDB 0,[POINT 27,1(2),35] ;Get lbn of current entry ?
CAMN 0,1 ;No, is this entry the one requested ?
JRST GETNT2 ;Yes
ADDI 2,3 ;Bump the pointer
CAIL 2,DBEND(DSW) ;Have we searched entire data base ?
JRST GETNTX ;Yes
JRST GETNT1 ;No, continue
GETNT2: MOVEM 2,(P) ;Save the pointer on stack
AOS -2(P) ;And bump the return
GETNTX: GET 2 ;Restore the ac's
GET 0
RTN ;And exit
;Putent -- create/replace/delete mapout-data-base entries
;This routine is passed an lbn and a pointer to a 3-word entry
;Compatable with the mapout data base. this routine will either
;
; - Replace an existing entry with a new one
; - Delete an existing entry
; - Add a new entry to the data base
;
;The data base is kept sorted with each new operation by either
;Pushing or popping the entries forward or bakward as required.
;
;This routine assumes a delete entry situation when the first word
;Of the replacement entry (pointed to by ac2) is clear.
;
;The error return: rtn1 is taken only if you attempt to create a new
;Entry when the data base is full. not only will the error rtn be
;Taken but an error message stating the problem will be printed.
;
;This routine also tallies hard and soft error counters "hspots",
;"Sspots" in the dsb area for totals information.
;
;Calling seq:
;
; Move ac2, arg2 ;ptr to 3-word entry
; Move ac1, arg1 ;lbn
; Go putent ;make the entry
; Rtn-1 ;data base is full
; Rtn-2 ;done
PUTENT: PUT 0 ;Save ac's
PUT 1
PUT 2
PUT 3
PUT 4
PUT 5
PUT 6
PUT 7
;Setup: move the 3 word user entry into ac5,ac6,ac7
;Get desired lbn to ac3
;Get pointer to start of data base to ac4
;Bump return for rtn2 (assumes normal)
MOVE 5,(2) ;Gets 1st user word
DMOVE 6,1(2) ;Gets 2nd and 3rd user word
LDB 3,[POINT 27,1,35] ;Gets desired lbn (ldb is a precaution)
MOVEI 4,DBSTRT(DSW) ;Pointer to start of the data base
AOS ^D-8(P) ;Now ready for rtn2
;Check users 1st word. zero:cancel non-zero:add/replace
JUMPE 5,PCAN0 ;Doing a cancel entry
;Here because we're doing an add/replace type operation on data base entry
PRPL1: SKIPN 0(4) ;Is current data base entry available ?
JRST PRPLA ;Yes. go and insert here ...
LDB 2,[POINT 27,1(4),35] ;No. get lbn from the current entry
CAML 2,3 ;Compare current lbn to desired lbn
JRST PRPLLE ;Current lbn > = desired lbn
ADDI 4,3 ;Current lbn < desired lbn. incr pointer
CAIG 4,DBEND(DSW) ;Tried entire buffer ?
JRST PRPL1 ;No. now try next entry
JRST PRPLFL ;Yes... data base is full
PRPLLE: CAMG 2,3 ;Must decide if > or =
JRST PRPLA ;Current lbn = desired lbn
JFCL ;Current lbn < desired (this is an insert)
SKIPE DBEND-2(DSW) ;See if last entry in data base is empty !
JRST PRPLFL ;Nope...data base is full
PRPLLS: EXCH 5,0(4) ;Current lbn < desired lbn
EXCH 6,1(4) ; Here we start a replace and shuffle
EXCH 7,2(4) ; To insert new entry in the data base
JUMPE 5,PUTCNT ;If ac5=0 we're done (working on null data)
ADDI 4,3 ;Not done. bump pointer
CAIGE 4,DBEND(DSW) ;At end of the data base ?
JRST PRPLLS ;No. keep the shuffle going
JRST PUTCNT ;End of data base. done.
;Here to do a straight 1 for 1 replacement
PRPLA: MOVEM 5,(4) ;Puts 1st word away
DMOVEM 6,1(4) ;Puts 2nd and 3rd words away
JRST PUTCNT ;Done. go tally the entries
;Here to print the data base full message. here we also back up the
;Return addr on the stack for rtn1 ...
PRPLFL: TEXT [ASCIZ/
MAPOUT DATA BASE FULL. LBN = /]
MOVE 0,3 ;Gets the lbn to ac0
GO POCDEC ;Print in octal and decimal
TEXT [ASCIZ/ NOT ENTERED
/]
SOS ^D-8(P) ;Adjust for rtn1
JRST PUTCNT ;We're done. go tally entries.
;Here because we're doing an entry deletion..
PCAN0: SKIPN 0(4) ;Is current entry null ?
JRST PUTCNT ;Yes. then we're done.
LDB 2,[POINT 27,1(4),35] ;Get lbn from this entry
CAMN 3,2 ;Is current lbn = desired lbn ?
JRST PCAN1 ;Yes
ADDI 4,3 ;No. bump pointer.
CAIG 4,DBEND(DSW) ;Searched the entire data base ?
JRST PCAN0 ;No. keep looking.
JRST PUTCNT ;Yes. done.
PCAN1: MOVE 5,3(4) ;Deleting current entry by shuffeling the
DMOVE 6,4(4) ; Rest of the data base back an entry ..
MOVEM 5,0(4) ; Which leaves the last entry blank
DMOVEM 6,1(4) ; For certian.
JUMPE 5,PUTCNT ;If ac5=0 we're into null data entries
ADDI 4,3 ;Bump pointer to next entry
CAIGE 4,DBEND-2(DSW) ;Go as far as 2nd last entry (this scheme)
JRST PCAN1 ;Not done. loop
SETZM DBEND-2(DSW) ;Done. zero the last entry
SETZM DBEND-1(DSW)
SETZM DBEND(DSW)
JRST PUTCNT ;We're done
;Finished desired operation. tally entries, restore ac's and exit
PUTCNT: GO DBCNT ;Tally entries in totals area
GET 7 ;Restore ac's
GET 6
GET 5
GET 4
GET 3
GET 2
GET 1
GET 0
RTN ;And exit
;Batsrt -- routine to sort the bat data base by lbn
;
; Calling seq:
; Go batsrt ;sort
; Rtn ;returns here always
BATSRT: PUT 1 ;Save some ac's
PUT 2
PUT 3
PUT 4
MOVEI 1,DBSTRT(DSW) ;Get pointer to data base
MOVE 2,1 ;To ac2 also
ADDI 2,3 ;Ac2 points to second entry of data base
BTSRT1: LDB 3,[POINT 14,(1),35] ;Get aprid field of ac1 entry
JUMPE 3,BTSRT2 ;Swap entries if it's empty
LDB 3,[POINT 14,(2),35] ;Get aprid field of ac2 entry
JUMPE 3,BTSRT3 ;Don't swap if it's empty
LDB 3,[POINT 27,1(1),35] ;Get lbn of entry pointed to by ac1
LDB 4,[POINT 27,1(2),35] ;Get lbn of entry pointed to by ac2
CAMG 3,4 ;Is it > lbn of entry pntd to by ac2 ?
JRST BTSRT3 ;No, don't swap
; Swap the two entries pointed to by ac1 and ac2
BTSRT2: DMOVE 3,(1) ;Get 1st & 2nd words of entry
EXCH 3,(2) ;Swap 1st words
EXCH 4,1(2) ;Swap 2nd words
DMOVEM 3,(1) ;Restore
MOVE 3,2(1) ;Get third word
EXCH 3,2(2) ;Swap third words
MOVEM 3,2(1) ;Restore
BTSRT3: ADDI 2,3 ;Bump ac2 pointer
CAIGE 2,DBEND(DSW) ;Have we finished this pass ?
JRST BTSRT1 ;No, continue
ADDI 1,3 ;Bump ac1 pointer
MOVE 2,1 ;And adjust ac2 pointer accordingly
ADDI 2,3
CAIGE 2,DBEND(DSW) ;Have we finished the sort ?
JRST BTSRT1 ;No, start next pass
BTSRTX: GET 4 ;Restore the ac's
GET 3
GET 2
GET 1
RTN ;And exit
;Dbcnt -- routine to count hard and soft errors in the data base
;
;This routine tallies hard and soft errors and returns the results in ac1
;On return, hard errors in ac1(r) and soft errors in ac1(l)
;
;Each time they are counted the values are moved to the hard and soft spot
;Counters "hspots", "sspots" in the dsb area.
;
; Call seq:
; Go dbcnt ;the call
; Rtn1 ;+1 ac1/soft count ,, hard count
DBCNT: PUT 2 ;Save ac's
PUT 3
SETZM 1 ;Counters now set to zero
MOVEI 3,DBSTRT(DSW) ;Point to start of the data base
DBFET: MOVE 2,(3) ;Fetch 1st word of entry
JUMPE 2,DBINC ;Non-entry if 1st wd is zero
MOVE 2,2(3) ;Good entry. get 3rd word
TLNE 2,400000 ;Is bbu=1 ?
ADDI 1,1 ;Yes. hard spot..
TLNN 2,400000 ;Is bbu=0 ?
ADD 1,[1,,0] ;Yes. soft spot..
DBINC: ADDI 3,3 ;Point to next entry
CAIGE 3,DBEND(DSW) ;At the end of data base ?
JRST DBFET ;No. fetch next entry and process
GET 3 ;Yes. restore ac's
GET 2
HRRZM 1,HSPOTS(DSW) ;Update hard spot counter
HLRZM 1,SSPOTS(DSW) ;Update soft spot counter
RTN ;And exit
;Makbat -- routine to write bat blocks to disk
;"Makbat" will write the first 61 entries of the bat data
;Base whose bbu bit = 1 to the bat blocks of the currently
;Selected disk.
;
;Call seq:
; Move 1,arg1 ;pointer to write data buffer
; Go makbat ;call the routine
; Rtn ;returns here always
MAKBAT: TLNN DSW,(1B10) ;Is there user data being protected ?
JRST MKBATG ;No continue
TEXTF [ASCIZ/
*****
RUNNING-MAPOUT /]
GO RUNTMF ;Print runtime
PCRLF
GO UNITF ;Print rh, drive, etc
TEXTF [ASCIZ/
BAT BLOCKS "NOT" WRITTEN BECAUSE THERE IS USER DATA ON THE MEDIA
*****/]
RTN ;Exit
;Ok to write bat blocks now
MKBATG: PUT 0 ;Save some ac's
PUT 1
PUT 2
PUT 3
MOVE 2,1 ;Get data buffer address
MOVEI 1,2 ;First we'll do lbn 2
GO GENBAT ;Generate a clean bat block image
MOVEI 1,DBSTRT(DSW) ;Get pointer to bat data base
ADDI 2,4 ;Adjust output buffer pntr to first pair
SETZM 3 ;We'll use ac3 as an output counter
MAKBT1: LDB 0,[POINT 14,(1),35] ;Get aprid field
JUMPE 0,MAKBT3 ;It's an empty entry. we're done.
SKIPL 2(1) ;Is bbu=1 ?
JRST MAKBT2 ;No, don't use this entry
;The current data base entry is to be written to the bat block
;Ac1 points to data base and ac2 points into data buffer
MOVE 0,(1) ;Get first word of bat pair
MOVEM 0,(2) ;Move it to output buffer
MOVE 0,1(1) ;Get second word of bat pair
MOVEM 0,1(2) ;Move it to output buffer
ADDI 2,2 ;Adjust output buffer pointer
AOS 3 ;Bump output counter
CAIL 3,^D61 ;Is output buffer full ?
JRST MAKBT3 ;Yes
MAKBT2: ADDI 1,3 ;Adjust data base pointer
CAIGE 1,DBEND(DSW) ;Have we searched whole data base yet ?
JRST MAKBT1 ;No, continue
;We're now ready to write the bat blocks
;Ac3 now holds count of number of bat block entries
MAKBT3: MOVE 2,-2(P) ;Get pointer to write buffer
DPB 3,[POINT 9,2(2),8] ;Updates "nbs" in bat block
DPB 3,[POINT 9,2(2),17] ;Updates "nbr" in bat block
LDB 3,[POINT 7,MBCN,9] ;Pull rh # out of mbcn
DPB 3,[POINT 7,2(2),24] ;Updates "kdc" in bat block
MAKB3A: MOVEI 1,2 ;First we'll do lbn 2
GO ADCON ;Convert to disk addr
MOVEI 1,61 ;A write data command
MOVE 3,-2(P) ;Buffer address
HRL 3,CWRWD(X1) ;+Wc,,addr
GO XFSTRT ;Start the xfer
GO IOWAIT
GO BRANCH ;To altmode routine
JRST MAKBTX ;Altmode was struck
JRST MAKB3A ;Loop
MKBT4: MOVEI 1,13 ;Now we'll do lbn 13
MOVE 3,-2(P) ;Pointer to output buffer
MOVEM 1,^D127(3) ;Lbn to buffer
GO ADCON ;Convert to disk addr
MOVEI 1,61 ;Write data command
HRL 3,CWRWD(X1) ;+Wc,,buffer addr
GO XFSTRT ;Start the transfer
GO IOWAIT ;Wait for completion
GO BRANCH ;Altmode routine
JRST MAKBTX ;Altmode struck
JRST MKBT4 ;Loop
MAKBTX: GET 3 ;Restore the ac's
GET 2
GET 1
GET 0
RTN ;And exit
;Batdsb -- merges bat block entries into the mapout data base
;This routine takes bat block entries and merges them into the mapout
;Data base located in the dsb area.
;
;A valid bat block entry is one whose first word is non-zero, and,
;An lbn that is a legal value for this type of drive ...
;
;Call seq:
; Move 1,arg1 ;pointer to start of bat block
; Go batdsb ;the call
; Rtn ;rtn+1
BATDSB: PUT 1 ;Save ac's
PUT 2
PUT 3
MOVE 3,1 ;Pointer to bat block data
ADDI 3,4 ;Point to 1st bad region pair
HRLI 3,^D-61 ;-# Of entries makes ac3 = -cnt,,ptr
BDSB1: SKIPN 0(3) ;Is this entry a valid entry ?
JRST BDSBN ;No. update pointer and loop
LDB 0,[POINT 27,1(3),35] ;Pull out the lbn ...
CAMLE 0,LBCE(X1) ;Is it a legal lbn for this drive ?
JRST BDSBN ;No... don't merge. bat block is wrong.
MOVE 2,0(3) ;Yes. fetch 1st word
MOVEM 2,ENT1 ;Put in edit buffer
MOVE 2,1(3) ;Fetch 2nd word
MOVEM 2,ENT2 ;Put into edit buffer
LDB 2,[POINT 27,ENT2,35] ;Pick up lbn
MOVEM 2,LBN ;Save for consistancy
SETZM ENT3 ;Edit buffer now properly initialized
;Look up entry in data base ...
BDSB2: MOVE 1,LBN ;Get lbn
GO GETENT ;Look for the entry
JRST BDSB3 ;Entry not there. this is a new one.
GO MERGEB ;Existing entry, merge 2 together
JRST BDSB4 ;Now make an data base update
;New entry, initialize for data base update
BDSB3: HRLZI 1,440000 ;Sets bbu=bat=1
IORM 1,ENT3 ;Status word is now set to go
;Now move the edit buffer into the data base
BDSB4: MOVEI 2,ENT1 ;Pointer to the edit buffer
MOVE 1,LBN ;And the logical block number
GO PUTENT ;Moves it to the data base
JFCL ;Rtn1... data base full
JRST BDSBN ;Rtn2... done
;Update bat block counter,,pointer and loop if necessary
;Count = count+1 and pointer = pointer+2
BDSBN: ADDI 3,1 ;Bumps pointer
AOBJN 3,BDSB1 ;Finishes pointer update and test for done
BDSBX: GET 3 ;Done. restore ac's
GET 2
GET 1
RTN
;Subroutine merges existing entry with a bat block entry.
;Ac2 points to data base entry. build bat entry in ent1, ent2, ent3
;The data from the bat block is considered the most important of the 2
; Entries, so what we actually do here is merge the data base entry into
; The existing bat block entry. the operator bits to enable or disable
; Bat block updatind takes priority when it comes to updating bbu ..
;
; Call seq:
; Move 2,arg2 ;pointer to data base entry.
; Go mergeb ;merge together in the edit buffer
; Rtn1 ;+1 always
MERGEB: PUT 0 ;Save ac's
PUT 1
PUT 2
HRRZ 1,0(2) ;Gets knm, aprid from data base
HRRZ 0,ENT1 ;Gets knm, aprid from edit buffer
CAMN 0,1 ;Are they the same
JRST MERG1 ;Yes. no update is necessary
MOVSI 1,(1B9) ;Not equal. set the mul bit
IORM 1,ENT1 ; In entry word-1
MERG1: MOVE 0,0(2) ;Get data base entry word-1
AND 0,[777,,0] ;Save the pub field and mul bit
IORM 0,ENT1 ;(Or) into pub field of edit buffer
LDB 0,[POINT 9,ENT1,8] ;Get region from edit buffer
LDB 1,[POINT 9,0(2),8] ;Get region from data base entry
CAMGE 0,1 ;Is the edit buffer value greater ?
DPB 1,[POINT 9,ENT1,8] ;No. then use region from data base
MOVE 1,2(2) ;Get entry word-3 from data base
TLO 1,(1B3) ;Set bat=1
TLNN 1,(1B2) ;Has operator cancelled bat block update ?
TLO 1,(1B0) ;No. then set bbu=1 in entry word-3
MOVEM 1,ENT3 ;And save updated version in the edit buffer
GET 2 ;Restore ac's
GET 1
GET 0
RTN ;And exit
;Prgent -- create a mapout entry from program code
;The program calls this routine to make a mapout entry or to update
;An existing mapout entry.
;
;The program supplies in ac2, a physical disk address pointing to the
;Block "after" the one that fails. this is where the disk address registers
;Normally point after a data error anyway. the mapout entry/modification
;Will be made for the block just prior to this one.
;
;The program supplies in ac1, a partial image of entry word-3 of a data
;Base entry. this routine looks at the following bits of that word:
;
; Bits 08-14 are (or'd) in as the status field
; Bits 18-26 are added to the hard error count
; Bits 27-35 are added to the soft error count
;
;The routine does the following:
;
; Updates data base entry words 1-2 as required
; Updates hard/soft error counters and overflow flags as requires
; Updates error status bits in entry word-3 as required
; Sets bbu=1 only if hard error and cbu=0
;
;Calling sequence:
; Move 1,arg1 ;image word for data base update
; Move 2,arg2 ;cylinder,,surf,sect (18,,8,8)
; Go prgent ;call the routine
; Rtn1 ;data base is full
; Rtn2 ;done
PRGENT: PUT 4 ;Save ac's
PUT 3
PUT 2
PUT 1
SETOM 1 ;A flag for adcon
GO ADCON ;Convert to lbn
SUBI 1,1 ;Adjust to correct address
CAMLE 1,LBCE(X1) ;See if we have a legal value
ILLADD: JRST PRGENX ;Illegal... not sure if this is possible
MOVEM 1,LBN ;Save the lbn
GO GETENT ;Look lbn up in the data base
JRST PRGEN1 ;Not there yet
MOVE 2,2 ;Lbn there .. ac2 points to entry
MOVEI 1,ENT1 ;Pointer to edit buffer
GO ENTOLD ;Do a partial merge ...
JRST PRGEN2 ;To some common code
PRGEN1: MOVE 1,LBN ;Get lbn to ac1
MOVEI 2,ENT1 ;Pointer to edit buffer
GO ENTNEW ;Create a new entry in edit buffer
PRGEN2: MOVE 4,ENT3 ;Get entry wd-3 to ac4 for manipulation
TLO 4,(1B4) ;Set pgm=1
MOVE 2,0(P) ;Get image from the stack
AND 2,[1770,,0] ;Save error bits field (08-14)
IOR 4,2 ;(Or) in the users error bits
;Process hard errors if necessary
LDB 2,[POINT 9,(P),26] ;Get hard error count from image
JUMPE 2,PRGEN3 ;Jump if no hard error update is necessary
TLNN 4,(1B2) ;See if user has cancelled bat block update
TLO 4,(1B0) ;No. hard error, set bbu=1
LDB 1,[POINT 9,4,26] ;Get hard entry count from ent3
ADD 1,2 ;Sum the 2 counts
DPB 1,[POINT 9,4,26] ;And save in entry word-3
TRNE 1,1B26 ;Did the field overflow ?
TLO 4,(1B16) ;Yes. set heo=1
;Process soft errors if necessary
PRGEN3: LDB 2,[POINT 9,(P),35] ;Get soft errors from image word
JUMPE 2,PRGEN4 ;None to process
LDB 1,[POINT 9,4,35] ;Get soft count from entry word-3
ADD 1,2 ;Sum the 2 counts
DPB 1,[POINT 9,4,35] ;And save in entry word-3
TRNE 1,1B26 ;Did the field overflow ?
TLO 4,(1B17) ;Yes. set seo=1
;Save back in edit buffer and then move edit buffer into the data base
PRGEN4: MOVEM 4,ENT3 ;Save in the edit buffer
MOVE 1,LBN ;Get the lbn to ac1
MOVEI 2,ENT1 ;Pointer to the edit buffer
GO PUTENT ;Put the entry away
SKIPA ;Data base full. take rtn1.
PRGENX: AOS -4(P) ;Bump return for rtn2
GET 1 ;Restore ac's
GET 2
GET 3
GET 4
RTN ;And exit
;Ckenpt -- check data base entry for print status
;This routine is called from the program to determine if an
;Error from a particular disk address is to be reported this time or not.
;
;The program supplies in ac2, a physical disk address of the block
;Followinf the one that failed. this is the normal way the disk
;Address registers point following a data error.
;
;The conditions for printing:
; - Entry not yet in the data base
; - Entry is in data base but pnt=1 (operator forcing printing)
; - "Palers" sense switch is set to a one
;
; The conditions for not printing:
; - Entry in data base, pnt=0 and, "palers" sense switch clear
;
;Calling seq:
; Move 2,arg2 ;cyl,,surf,sect (18,,8,8)
; Go ckenpt ;call the routine
; Rtn1 ;don't report this error
; Rtn2 ;report this error
CKENPT: PUT 1 ;Save ac's
PUT 2
MOVE 1,CONSW ;Get console switches
TLNE 1,001000 ;Is palers set ?
JRST CKENX2 ;Yes. then we're done
SETOM 1 ;Ac1 to -1 for adcon
GO ADCON ;Convert to lbn
SUBI 1,1 ;Now pointing to correct block
GO GETENT ;Lookup the lbn in the data base
JRST CKENX2 ;Not there. then we're done
MOVE 1,2(2) ;There. fetch third word in entry
TLNE 1,(1B6) ;Is the pnt bit=1 ?
CKENX2: AOS -2(P) ;Yes. take return-2
CKENX1: GET 2 ;Restore ac's
GET 1
RTN ;And exit
END