Trailing-Edge
-
PDP-10 Archives
-
bb-m780a-sm
-
monitor-sources/swpalc.mac
There are 48 other files named swpalc.mac in the archive. Click here to see a list.
; UPD ID= 1568, SNARK:<5.MONITOR>SWPALC.MAC.3, 19-Feb-81 13:58:26 by HALL
;TCO 5.1180 - MAKE THE BUGHLT IN GDSTX BE PERMANENT, BUT UNDER A
; CONDTIONAL
; UPD ID= 1197, SNARK:<5.MONITOR>SWPALC.MAC.2, 25-Oct-80 12:15:05 by HALL
;TCO 5.1180 - MOVE THE DST INTO NON-ZERO SECTION
; GDSTX -- RETURN ADDRESS RATHER THAN OFFSET INTO DST
; SWPINI -- CALL SETDST TO INITIALIZE PAGING STUFF
;<OSMAN.MON>SWPALC.MAC.1, 10-Sep-79 16:05:48, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>SWPALC.MAC.1, 11-Mar-79 12:59:35, Edit by KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG
TTITLE(SWPALC,,< - SWAPPING SPACE ALLOCATION>)
;SWAP STORAGE ALLOCATOR
;THIS ALLOCATOR HANDLES A DEVICE OF SOME NUMBER (SWPSEC) OF SECTORS,
;AND SOME NUMBER (DRMMXB) OF TRACKS (BANDS). IT HAS A RESIDENT BIT TABLE,
;AND IS USED TO ALLOCATE SWAPPING STORAGE, EVEN IF THE PHYSICAL
;SWAPPING DEVICE IS THE SAME AS THE PHYSICAL FILE DEVICE
;PARAMETERS DRMSEC AND NTRK OF THE PHYSICAL DRUM ARE ALSO USED
;TO DETERMINE THE NUMBER OF PAGES ON THE ACTIVE PHYSICAL DRUMS
;** THE ACTUAL DRUM DRIVER IS ASSEMBLED AHEAD OF THIS ALLOCATOR **
;*** ALLOCATOR ***
EXTN <SWPSEC,DRMMXB,DRMBSZ,NPDRMS,MAXDRA,DRMBND,MDRMBD>
EXTN <DRMTPG,DRMBBT,DRMCNT,DRMBN0,DRMFRE>
EXTN <DRMSEC,NTRK,DRMINI>
;ASSIGN DRUM PAGE, FREE CHOICE
; CALL DRMASN
; RETURN +1: DRUM FULL
; RETURN +2: PAGE ASSIGNED, A/ DRUM ADDRESS
DRMASN::SKIPG DRMFRE ;ANY SPACE ON DRUM?
RET ;NO, FAIL
SE1CAL
MOVE A,DRMBN0 ;GET LAST TRACK ASSIGNED
SKIPE DRMCNT(A) ;ANY FREE ON THAT TRACK?
JRST DRMAS3 ;YES, GOOD ONE TO USE
HRLZ A,MDRMBD ;NO, HAVE TO SEARCH. SETUP AOBJN PTR
SKIPG DRMCNT(A) ;ANY FREE ON THIS TRACK?
AOBJN A,.-1 ;NO
JUMPGE A,DRMBUG ;JUMP IF COULDN'T FIND ANY SPACE
DRMAS3: MOVEI A,0(A) ;GET TRACK NUMBER
MOVEM A,DRMBN0 ;REMEMBER LAST TRACK ASSIGNED
IMULI A,DRMBSZ ;COMPUTE INDEX TO BITS FOR THIS TRACK
ADDI A,DRMBBT
HRLI A,400002 ;SET UP INDEX INDIRECT OF B
MOVSI B,-DRMBSZ ;SETUP TO SCAN BIT WORDS
DRMAS2: SKIPE C,@A ;GET BITS
JFFO C,DRMAS1 ;FREE BIT HERE?
AOBJN B,DRMAS2 ;NO, GO TO NEXT WORD
DRMBUG: BUG(DRMIBT)
DRMAS1: MOVE C,BITS(D) ;GET THE BIT JUST FOUND
ANDCAM C,@A ;MAKE IT IN USE
MOVEI B,0(B) ;GET WORD NUMBER WITHIN TRACK GROUP
IMULI B,^D36 ;COMPUTE SECTOR NUMBER JUST ASSIGNED
ADDI B,0(D)
MOVE A,DRMBN0 ;RECOVER TRACK NUMBER
SOS DRMCNT(A) ;UPDATE FREE COUNT OF TRACK
SOS DRMFRE ;UPDATE FREE COUNT OF DRUM
CALL DRMMKA ;MAKE DRUM ADDRESS FROM TRACK AND SECTOR
RETSKP
;MAKE DRUM ADDRESS FROM TRACK AND SECTOR
; A/ TRACK NUMBER
; B/ SECTOR NUMBER
; CALL DRMMKA
; RETURN +1: ALWAYS, A/ DRUM ADDRESS
DRMMKA: IMULI A,SWPSEC ;COMPUTE LINEAR PAGE ADDRESS
ADD A,B
CAML A,MAXDRA ;ON OVERFLOW DEVICE?
JRST [ SUB A,MAXDRA ;YES, FORM ADDRESS ON OVERFLOW DEVICE
MOVE C,STRTAB ;POINT TO SDB FOR PUBLIC STRUCTURE
MOVE C,SDBTYP(C) ;POINT TO SIZE DATA FOR THIS DISK TYPE
IMUL A,SECPAG(C) ;CONVERT TO SECTORS
TXO A,DRMOB ;INDICATE OVERFLOW
JRST DRMMK1]
IDIVI A,DRMSEC ;CONVERT TO PHYSICAL DRUM TRACK AND SECTOR
STOR A,DRTRK,A ;CONSTRUCT ADDRESS
STOR B,DRSEC,A
DRMMK1: TXO A,DRMAB ;INDICATE SWAPPING ADDRESS
RET
;ASSIGN SPECIFIC DRUM ADDRESS
; 1/ ADDRESS TO BE ASSIGNED
; CALL DRMASA
; RETURN +1: FAILED, ADDRESS ILLEGAL OR ALREADY ASSIGNED
; RETURN +2: SUCCESSFUL
DRMASA::SE1CAL
CALL DRMGTS ;GET TRACK AND SECTOR
JRST RFALSE ;ILLEGAL ADDRESS
PUSH P,A ;SAVE TRACK
IMULI A,DRMBSZ ;COMPUTE INDEX TO PROPER BIT WORD
IDIVI B,^D36
ADDI B,0(A)
POP P,A ;RECOVER TRACK
MOVE C,BITS(C) ;GET BIT FOR SECTOR
TDNN C,DRMBBT(B) ;SECTOR NOW FREE?
JRST RTRUE ;NO. FAIL
ANDCAM C,DRMBBT(B) ;YES, MARK IT IN USE
SOS DRMCNT(A) ;UPDATE TRACK FREE COUNT
SOS DRMFRE ;UPDATE DRUM FREE COUNT
RETSKP
;LOCAL ROUTINE TO GET TRACK AND SECTOR FROM DRUM ADDRESS
; 1/ DRUM ADDRESS
; CALL DRMGTS
; RETURN +1: ILLEGAL ADDRESS
; RETURN +2: A/ TRACK NUMBER, B/ SECTOR NUMBER
DRMGTS: TXZ A,-1B<POS(DRMOB)-1> ;EXTRACT ADDRESS BITS
TXZE A,DRMOB ;OVERFLOW ADDRESS?
JRST [ MOVE C,STRTAB ;YES. POINT TO SDB FOR PUBLIC STRUCTURE
MOVE C,SDBTYP(C) ;POINT TO SIZE DATA FOR THIS DISK TYPE
IDIV A,SECPAG(C) ;CONVERT TO LINEAR PAGE ADDRESS
ADD A,MAXDRA ;SWP ADDR BASE FOR OVERFLOW DEVICE
JRST DRMGT1]
LOAD B,DRSEC,A ;GET SECTOR
LOAD A,DRTRK,A ;GET TRACK
IMULI A,DRMSEC ;COMPUTE LINEAR PAGE ADDRESS
ADD A,B
DRMGT1: IDIVI A,SWPSEC ;CONVERT TO TRACK AND SECTOR
CAML A,DRMBND ;WITHIN RANGE?
RET ;NO, FAIL
RETSKP ;YES
;DEASSIGN DRUM ADDRESS
; 1/ DRUM ADDRESS
; CALL DASDRM
; RETURN +1: ALWAYS (BUGCHK IF BAD OR UNASSIGNED ADDRESS)
DASDRM::SE1CAL
CALL DEDRM ;DO THE WORK
BUG(ILDRA1)
RET
;DEASSIGN DRUM ADDRESS
; 1/ DRUM ADDRESS
; CALL DEDRM
; RETURN +1: BAD OR UNASSIGNED DRUM ADDRESS
; RETURN +2: SUCCESS, ADDRESS DEASSIGNED
DEDRM:: SE1CAL
CALL DRMGTS ;GET TRACK AND SECTOR FROM ADDRESS
RET ;ILLEGAL ADDRESS, FAIL
PUSH P,A ;SAVE TRACK
IMULI A,DRMBSZ ;COMPUTE INDEX TO PROPER BIT WORD
IDIVI B,^D36
ADDI B,0(A)
POP P,A ;RECOVER TRACK
MOVE C,BITS(C) ;GET BIT FOR SECTOR
TDNE C,DRMBBT(B) ;NOW ASSIGNED?
RET ;NO, FAIL
IORM C,DRMBBT(B) ;MARK IT FREE
AOS DRMCNT(A) ;UPDATE TRACK FREE COUNT
AOS DRMFRE ;UPDATE DRUM FREE COUNT
RETSKP
;ASSIGN MULTIPLE CONTIGUOUS DRUM ADDRESSES
; 1/ NUMBER OF CONTIGUOUS PAGES DESIRED
; CALL DRMAM
; RETURN +1: ALWAYS,
; A/ NUMBER OF CONTIGUOUS PAGES ACTUALLY FOUND
; B/ ADDRESS OF FIRST OF GROUP OF CONTIGUOUS PAGES
;PAGES ARE NOT ACTUALLY ASSIGNED HERE, CALLER MUST ASSIGN PAGES
;INDIVIDUALLY AS THEY ARE SUBSEQUENTLY USED
;AC USAGE:
; Q1 - AOBJN PTR TO SCAN TRACKS
; Q2 - DESIRED N FROM CALLER
; Q3 - MAX CONTIGUOUS PAGES FOUND SO FAR
; P1 - TRACK,,SECTOR OF FIRST PAGE OF BEST CONTIGUOUS GROUP
DRMAM:: SKIPG DRMFRE ;ANY SPACE ON DRUM?
RET ;NO, FAIL
SE1CAL
PUSH P,Q1
PUSH P,Q2
PUSH P,Q3
PUSH P,P1
MOVEM A,Q2 ;SAVE DESIRED COUNT
DRMAM6: HRLZ Q1,MDRMBD ;SETUP TO SCAN TRACKS
SETZ Q3, ;INIT MAX
DRMAM2: CAMG Q2,DRMCNT(Q1) ;ENOUGH FREE PAGES THIS TRACK FOR REQUEST?
JRST DRMAM3 ;YES, GO CHECK IT
DRMAM4: AOBJN Q1,DRMAM2 ;LOOP OVER TRACKS
JUMPG Q3,DRMAM5 ;JUMP IF HAVE FOUND SOMETHING
ASH Q2,-1 ;FOUND NO TRACK WITH N, REDUCE N
JUMPG Q2,DRMAM6 ;TRY AGAIN UNLESS N NOW 0
BUG(DRMNFR)
;HERE WHEN HAVE A TRACK WITH .GE. N FREE PAGES. PAGES MAY OR MAY NOT
;BE CONTIGUOUS HOWEVER.
DRMAM3: CALL DRMBG ;GET MAX CONTIGUOUS GROUP ON THIS TRACK
CAMLE A,Q3 ;BEST GROUP SO FAR?
JRST [ MOVEM A,Q3 ;YES, SAVE COUNT
MOVEM B,P1 ;SAVE SECTOR NUMBER
HRLM Q1,P1 ;SAVE TRACK NUMBER
JRST .+1]
CAMGE Q3,Q2 ;ENOUGH TO SATISFY REQUEST?
JRST DRMAM4 ;NO, KEEP LOOKING
DRMAM5: HLRZ A,P1 ;GET TRACK
HRRZ B,P1 ;GET SECTOR
CALL DRMMKA ;MAKE DRUM ADDRESS
MOVE B,A ;RETURN IT IN B
MOVE A,Q3 ;GET COUNT TO RETURN
DRMAMX: POP P,P1
POP P,Q3
POP P,Q2
POP P,Q1
RET
;LOCAL ROUTINE TO FIND LARGEST CONTIGUOUS CLUSTER OF PAGES ON
;A TRACK.
; Q1/ TRACK NUMBER
; CALL DRMBG
; RETURN +1: ALWAYS,
; A/ MAX NUMBER OF CONTIGUOUS PAGES FOUND
; B/ SECTOR NUMBER OF FIRST PAGES OF GROUP
;AC USAGE:
; A/ NUMBER OF BITS LEFT TO EXAMINE IN CURRENT WORD
; B/ CURRENT BIT WORD
; C/ RESULT OF JFFO
; D/ NUMBER OF CONTIGUOUS BITS FOUND IN THIS GROUP
; Q1/ AOBJN PTR TO LOOP THROUGH ALL BIT WORDS FOR THIS TRACK
; Q2/ LH: SECTOR NUMBER OF FIRST SECTOR OF BEST GROUP SEEN
; RH: SECTOR NUMBER OF FIRST SECTOR OF CURRENT GROUP
; P1/ NUMBER OF CONTIGUOUS BITS IN BEST GROUP SEEN SO FAR
DRMBG: PUSH P,Q1
PUSH P,Q2
PUSH P,P1
MOVEI Q1,0(Q1) ;GET TRACK NUMBER
IMULI Q1,DRMBSZ ;COMPUTE INDEX TO BITS WORDS FOR THIS TRK
HRLI Q1,-DRMBSZ ;CONSTRUCT AOBJN PTR
SETZB Q2,P1 ;INIT MAX COUNT AND SECTOR NUMBER
SETZ D, ;INIT CURRENT COUNT
DRMBG3: MOVE B,DRMBBT(Q1) ;GET BIT WORD
MOVEI A,^D36 ;WE HAVE 36 BITS TO EXAMINE IN THIS WORD
DRMBG2: SETCA B, ;COMPLEMENT SO JFFO WILL FIND 0'S
JFFO B,.+2 ;SKIP OVER 1'S TO FIND FIRST 0
MOVEI C,0(A) ;NO 0'S, REST OF WORD IS 1'S
ADD D,C ;ADD COUNT TO COUNT FROM PREVIOUS WORDS
CAMLE D,P1 ;MAX COUNT SEEN SO FAR?
JRST [ MOVEM D,P1 ;YES, REMEMBER IT
HRLM Q2,Q2 ;AND REMEMBER FIRST SECTOR NUMBER
JRST .+1]
SUB A,C ;REDUCE BIT COUNT BY BITS JUST PASSED
JUMPLE A,DRMBG1 ;JUMP IF NO MORE BITS IN THIS WORD
SETCA B, ;GET TRUE WORD BACK
LSH B,0(C) ;SHIFT OUT BITS JUST PASSED
ADDM D,Q2 ;UPDATE SECTOR NUMBER FOR BITS NOW PASSED
SETZ D, ;SET NO BITS IN PREVIOUS WORD
JFFO B,.+2 ;SKIP 0'S TO FIND A 1
MOVEI C,0(A) ;NO 1'S IN REST OF WORD
SUB A,C ;REDUCE BIT COUNT BY BITS JUST PASSED
ADDM C,Q2 ;UPDATE SECTOR NUMBER FOR BITS JUST PASSED
LSH B,0(C) ;SHIFT OUT 0'S JUST PASSED
JUMPG A,DRMBG2 ;JUMP IF MORE BITS IN THIS WORD
DRMBG1: AOBJN Q1,DRMBG3 ;LOOK AT ALL BIT WORD FOR THIS TRACK
DRMBG4: MOVE A,P1 ;GET MAX COUNT SEEN
HLRZ B,Q2 ;GET SECTOR NUMBER
POP P,P1
POP P,Q2
POP P,Q1
RET
;CONVERT DRUM ADDRESS INTO INDEX INTO DST
; 2/ DRUM ADDRESS
; CALL GDSTX
; RETURN +1: ALWAYS, 2/ ADDRESS WITHIN DST
;PRESERVES T1 AND T4
GDSTX::
;IF THE CALLER OF THIS ROUTINE IS RUNNING IN SECTION 0 ON AN EXTENDED
;ADDRESSING MACHINE, THERE MAY BE TROUBLE LATER WHEN THE CALLER USES
;THE ADDRESS RETURNED BY THIS ROUTINE. THIS ROUTINE RETURNS AN ADDRESS
;IN A NON-ZERO SECTION, AND THE CALLER PROBABLY DOES AN INDEXED REFERENCE
;TO THAT ADDRESS. IN SECTION 0, THE LEFT HALF OF THE AC WILL BE IGNORED.
;THE CODE UNDER THE CONDTIONAL TESTS FOR THIS CASE AND BUGHLT'S, THUS
;AVERTING LATER DISASTER.
IFN SEC0SW,< ;IF TESTING FOR RUNNING IN SECTION 0
MOVX CX,VSECNO ;GET SECTION NUMBER MASK FOR PC
TDNN CX,0(P) ;CHECK THE CALLING PC
BUG (GDSTX0,<<0(P),PC>>)
> ;END OF IFN SEC0SW
TLNN 2,14 ;INSIST ON REGULAR DRUM ADDRESS
TLNN 2,2
BUG(ILGDA1)
TXZ 2,-1B<POS(DRMOB)-1> ;EXTRACT ADDRESS BITS
TXZE 2,DRMOB ;AN OVERFLOW ADDRESS?
JRST [ MOVE C,STRTAB ;YES. POINT TO SDB FOR PUBLIC STRUCTURE
MOVE C,SDBTYP(C) ;POINT TO SIZE DATA FOR THIS DISK TYPE
IDIV 2,SECPAG(C) ;CONVERT TO PAGE UNITS
ADD 2,MAXDRA ;SWP ADDR BASE FOR OVERFLOW DEVICE
JRST GDSTX1]
LOAD C,DRSEC,B ;GET SECTOR
LOAD B,DRTRK,B ;GET TRACK
IMULI B,DRMSEC ;COMPUTE LINEAR PAGE ADDRESS
ADD B,C
GDSTX1: CAIL 2,NDST
BUG(ILGDA2)
ADD 2,DSTLOC ;MAKE IT AN ADDRESS
RET
;INCREMENT DRUM ADDRESS - USED TO GET NEXT ADDRESS IN GROUP WHEN
;CONSTRUCTING MULTIPLE-PAGE SWAP
; 1/ DRUM ADDRESS
; CALL DRMIAD
; RETURN +1: ALWAYS, A/ DRUM ADDRESS 1 PAGE BEYOND ARGUMENT
DRMIAD::SE1CAL
CALL DRMGTS ;GET TRACK AND SECTOR
BUG(ILDRA2)
ADDI B,1 ;INCREMENT SECTOR
CAIL B,SWPSEC ;BEYOND END OF TRACK?
JRST [ SETZ B, ;YES, RESET TO SECTOR 0
AOJA A,.+1] ;GO TO NEXT TRACK
CALLRET DRMMKA ;RECONSTRUCT ADDRESS AND RETURN
;ROUTINE TO INITIALIZE BIT TABLE FOR A TRACK
; A/ TRACK NUMBER
; CALL DRMTKI
; RETURNS +1: ALWAYS, ALL PAGES ON TRACK SET FREE
DRMTKI: MOVEI B,SWPSEC ;INIT COUNT FOR TRACK
MOVEM B,DRMCNT(A)
IMULI A,DRMBSZ ;COMPUTE INDEX TO FIRST WORD OF BITS
ADDI A,DRMBBT
HRLI A,400002 ;SET UP INDIRECT B
MOVSI B,-DRMBSZ ;SETUP AOBJN PTR TO INIT ALL BIT WORDS
SETOM @A ;SET ALL PAGES FREE IN THIS WORD
AOBJN B,.-1
MOVEI B,SWPSEC
IDIVI B,^D36 ;COMPUTE NUMBER BITS IN LAST WORD
JUMPE C,R ;PERHAPS NONE
MOVNI B,-1(C) ;SETUP TO CONSTRUCT BIT WORD
MOVX C,1B0 ;GET A BIT
ASH C,0(B) ;REPLICATE IT
MOVEI B,DRMBSZ-1 ;MAKE PTR TO LAST BIT WORD
MOVEM C,@A ;SET LAST (PARTIAL WORD
RET
;ROUTINE TO ASSIGN ALL PAGES FOR A TRACK IN CASE TRACK BAD
; A/ TRACK NUMBER
; CALL DRMTLK
; RETURN +1: ALWAYS, TRACK SET TO 0 FREE
DRMTLK: SETZM DRMCNT(A) ;SET COUNT TO 0
IMULI A,DRMBSZ ;GET PTR TO FIRST WORD OF BITS
ADDI A,DRMBBT
HRLI A,400002 ;SET UP FOR @A
MOVSI B,-DRMBSZ ;SETUP TO REF ALL BIT WORDS
SETZM @A ;CLEAR ALL BITS
AOBJN B,.-1
RET
;INITIALIZE DRUM BIT TABLES
SWPINI::
CALL SETDST ;SET UP THE SECTION MAP AND DSTLOC
SETZM NPDRMS ;DECLARE 0 PHYSICAL UNLESS DRMINI CHANGES
CALL DRMINI ;INIT DEVICE DRIVER, COUNT PHYSICAL UNITS
MOVE A,NPDRMS ;GET NUMBER OF PHYSICAL UNITS
IMULI A,NTRK*DRMSEC ;COMPUTE NUMBER OF PAGES OF PHYS UNITS
MOVEM A,MAXDRA ;IT MARKS BOUNDARY BETWEEN DRUM AND DISK SWAP
CALL DRMISP ;INIT STORAGE PARAMETERS
HRLZ D,MDRMBD ;SETUP TO INIT ALL TRACKS
MOVEI A,0(D) ;GET TRACK NUMBER
CALL DRMTKI ;INIT THE TRACK
AOBJN D,.-2
MOVE A,DRMTPG ;GET TOTAL NUMBER PAGES ON DRUM
CAILE A,NDST ;CHECK AGAINST DST
BUG(DST2SM)
MOVEM A,DRMFRE
CALL SETSSP ;SETUP LIMITS BASED ON DRUM SPACE
SKIPG DRUMP ;REAL DRUM ON SYSTEM?
RET ;NO, DON'T ASSIGN RESERVED ADDRESSES
PUSH P,Q1
MOVSI Q1,-NDRMBA ;SETUP TO ASSIGN BAD ADDRESSES
DRMIN2: MOVE A,DRMBAT(Q1) ;GET A BAD ADDRESS
JUMPL A,DRMIN1 ;JUMP IF END OF LIST
CALL DRMASA ;ASSIGN THE ADDRESS
BUG(ASGSWB)
AOBJN Q1,DRMIN2
DRMIN1: POP P,Q1
RET
;SETUP SWAP STRUCTURE PARAMETERS BASED ON NDST
DRMISP: MOVEI A,NDST ;GET MAX NUMBER PAGES FOR SWAPPING
MOVE B,NSSUN ;GET # OF DISK SECTORS RESERVED
MOVE C,STRTAB ;POINT TO SDB FOR PUBLIC STRUCTURE
MOVE D,SDBTYP(C) ;POINT TO SIZE DATA FOR THIS DISK TYPE
IDIV B,SECPAG(D) ;CONVERT NUMBER SWAP SECTORS TO PAGES
MOVE C,STRTAB ;POINT TO SDB FOR PUBLIC STRUCTURE
IMUL B,SDBNUM(C) ;GET TOTAL DSK PAGES RESERVED
ADD B,MAXDRA ;ADD DRUM PAGES AVAILABLE
CAMLE A,B ;GET MINIMUM AMOUNT
MOVE A,B ;LIMITED TO SPACE RESERVED ON DISK & DRUM
MOVEM A,DRMTPG ;SAVE TOTAL DRUM PAGES
IDIVI A,SWPSEC ;COMPUTE TOTAL NUMBER TRACKS
MOVEM A,DRMBND
MOVNM A,MDRMBD ;KEEP NEGATIVE ALSO FOR CONVENIENCE
RET
;BAD AND RESERVED ADDRESS TABLE
DRMBAT: -1 ;MARK END OF LIST
BLOCK 6 ;PATCH SPACE FOR ADDITIONAL BAD ADRS
NDRMBA==.-DRMBAT
TNXEND ;BUGSTRINGS, ETC.
END