From: SMTP%"tihor@acf4.NYU.EDU" 29-SEP-1990 16:21:18.78 To: tihor@acf4.NYU.EDU CC: Subj: Re: Sizing memory on VMS (source code) Received: from acf4.NYU.EDU by ACF7.NYU.EDU with SMTP; Sat, 29 Sep 1990 16:21:05 EDT Received: by acf4.NYU.EDU (5.61/1.34) id AA15909; Sat, 29 Sep 90 16:19:09 -0400 Date: Sat, 29 Sep 90 16:19:09 -0400 From: tihor@acf4.NYU.EDU (Stephen Tihor) Message-Id: <9009292019.AA15909@acf4.NYU.EDU> To: tihor@acf4.NYU.EDU Subject: Re: Sizing memory on VMS (source code) Newsgroups: comp.os.vms In-Reply-To: article <9009270823.AA09038@ucbvax.Berkeley.EDU> of 27 Sep 90 03:42 EDT /* acf4:comp.os.vms / NICK@ncdlab.ulcc.ac.uk (Nick de Smith) / 3:42 am Sep 27, 1990 */ Hi, Loads of requests for it, its small, so here it is... This code, I believe, is definitive. That is to say that it implements the same algorithms as used by SHOW MEMORY (as of VMS V5.3-1), which I presume to be correct. Hopefully my implementation of these algorithms is correct, and so this will kill another one of the perenial Info-VAX woolly arguments. I might point out that the VMS SHOW MEMORY code is on a fiche number > 999, which means that the fiche index shows it a being on page "***" (thanks guys!). Because of this, I had to go through the index of each sheet over 1000 (the sheet index is in the bottom right hand corner of each page), and aren't there just a lot of interesting, unsupported, utilities there! Not exactly bedtime reading, but a *real load* of good ideas. SHOW_MEMORY part 1 of 1 follows at the end of this message. The XFREEMEM.C code is largish (about 55 blocks), so I don't intend to repost it. It is a fairly trivial exercise to extract the SIZE_MEMORY routine from the code below, and to replace the equivalent code in XFREEMEM with it (should take about 5 minutes). regards, nick NICK@NCDLAB.ULCC.AC.UK (comments etc. are generally welcome) $! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 28-SEP-1990 08:26:48.82 By user NICK $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $!+ THIS PACKAGE DISTRIBUTED IN 1 PART, TO KEEP EACH PART $! BELOW 30 BLOCKS $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. SHOW_MEMORY.C;1 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X/*************************************************************************** V********************************************** X X Program`09: SHOW_MEMORY.EXE X Author`09`09: Nick de Smith`09`09NICK@NCDLAB.ULCC.AC.UK X Creation date`09: 23-Aug-90 X X `A9 1990 Nick de Smith and Applied Telematics Group Ltd. X This software is supplied for information only. No guarantee is supplied fo Vr this software, and no liability X will be accepted for any action resulting from the use of this software or V the information contained herein. X Under no circumstances may this software be used for commercial gain, inclu Vding its sale, lease or loan. X This software may be copied only with the inclusion of this copyright notic Ve. X The author is prepared to enter into correspondance with interested parties V, but will not necessarily X maintain this software. Having said all that, enjoy it! X X Edit`09Edit date`09By`09Why X 02`0925-Sep-90`09NMdS`09Add in percentage rounding fiddle factor. X 01`0923-Aug-90`09NMdS`09New X X Show system memory usage. Requires CMEXEC privilege. X This code, I believe, is definitive. That is to say that it implements the V same algorithms as used by SHOW MEMORY (as X of VMS V5.3-1), which I presume to be correct. Hopefully my implementation V of these algorithms is correct, and so this X will kill another one of the perenial Info-VAX woolly arguments. X X Build with:`09$ CC SHOW_MEMORY X`09`09$ LINK SHOW_MEMORY,SYS$SYSTEM:SYS.STB/SELECT X`09`09$ RUN SHOW_MEMORY X X**************************************************************************** V*********************************************/ X X#module`09SHOW_MEMORY`09"V01.02" X X#include`09descrip`09`09`09`09`09`09`09/* Define DSC$xxx - VAX descriptors`0 V9`09*/ X#include`09psldef`09`09`09`09`09`09`09/* Define PSL$xxx - Access mode symbol Vs`09`09*/ X#include`09ssdef`09`09`09`09`09`09`09/* Define SS$xxxx - System status codes V`09`09*/ X#include`09stsdef`09`09`09`09`09`09`09/* Define STS$M_xxxx - VMS status bits V`09`09*/ X X/* Useful macro to check returned status of a system routine */ X#define`09ss_check( command ) `7B`09`09`09\ X`09long ss_status = (command);`09`09\ X`09if ( (ss_status & STS$M_SUCCESS) == 0 ) `7B \ X`09`09return ss_status;`09`09\ X`09`7D`09`09`09`09`09\ X`7D X X/*************************************************************************** V********************************************** X X`09`09`09`09`09S H O W _ M E M O R Y X X Show the memory usage by this VMS system. X All displayed percentages are with respect to the ENABLED memory, not the t Votal on the system. X X**************************************************************************** V*********************************************/ X XSHOW_MEMORY() X`7B X`09static $DESCRIPTOR( x_format_1, "There are !UL physical page!%S (!UL.!AD V Mb) on this system" ); X`09static $DESCRIPTOR( x_format_10,"!_all of which is enabled" ); X`09static $DESCRIPTOR( x_format_11,"!_of which only !UL page!%S (!UL.!AD Mb) V are enabled" ); X`09static $DESCRIPTOR( x_format_2, "Pages Inuse: !UL (!UL%) Free: !UL (!UL% V) Modified: !UL (!UL%) Bad: !UL" ); X`09static $DESCRIPTOR( x_format_3, "Of the pages in use, !UL (!UL%) are perm Vanently allocated to VMS" ); X`09static struct dsc$descriptor_d x_output = `7B X`09`090, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 `7D; X`09unsigned long l_physical_pages;`09`09`09`09`09/* Physical pages in enable Vd for use`09`09*/ X`09unsigned long l_free_pages;`09`09`09`09`09/* Pages on free list`09`09`09` V09*/`20 X`09unsigned long l_modified_pages;`09`09`09`09`09/* Pages on modified list`0 V9`09`09*/ X`09unsigned long l_vms_pages;`09`09`09`09`09/* Pages in use by VMS`09`09`09` V09*/ X`09unsigned long l_bad_pages;`09`09`09`09`09/* Pages marked "bad"`09`09`09`0 V9*/ X`09unsigned long l_real_physical_pages;`09`09`09`09/* Physical pages connect Ved to system`09`09*/ X`09unsigned long args`5B`5D = `7B 6, X`09`09&l_physical_pages, &l_free_pages, &l_modified_pages, &l_vms_pages, &l_ Vbad_pages, &l_real_physical_pages `7D; X`09static int SIZE_MEMORY();`09`09`09`09`09/* CMEXEC routine to get memory s Vize.`09`09*/ X X`09ss_check( SYS$CMEXEC( SIZE_MEMORY, args ) )`09`09`09/* Call the data coll Vector`09`09`09*/ X X`09ss_check( LIB$SYS_FAO( X`09`09&x_format_1`09`09,`09`09`09`09/* Format control string`09`09`09*/ X`09`090`09`09`09,`09`09`09`09/* No resultant length`09`09`09`09*/ X`09`09&x_output`09`09,`09`09`09`09/* Output string`09`09`09`09*/ X`09`09l_real_physical_pages`09,`09`09`09`09/* Number of physical pages`09`09 V`09*/ X`09`09l_real_physical_pages >> 11,`09`09`09`09/* Number of megabytes of phys Vical memory`09*/ X`09`092, &"00255075"`5B ((l_real_physical_pages >> 9) & 3) * 2 `5D ) ) /* Fr Vactional part of Mb`09`09`09*/ X`09ss_check( LIB$PUT_OUTPUT( &x_output ) ) X X`09if ( l_real_physical_pages == l_physical_pages ) `7B`09`09/* If all memor Vy is enabled...`09`09`09*/ X`09`09ss_check( LIB$SYS_FAO(`09`09`09`09`09/* ...say all memory is enabled`0 V9`09`09*/ X`09`09`09&x_format_10`09`09,`09`09`09/* Format control string`09`09`09*/ X`09`09`090`09`09`09,`09`09`09/* No resultant length`09`09`09`09*/ X`09`09`09&x_output`09`09) )`09`09`09/* Output string`09`09`09`09*/ X`09`7D else `7B X`09`09ss_check( LIB$SYS_FAO(`09`09`09`09`09/* Say how much memory is enabled V`09`09*/ X`09`09`09&x_format_11`09`09,`09`09`09/* Format control string`09`09`09*/ X`09`09`090`09`09`09,`09`09`09/* No resultant length`09`09`09`09*/ X`09`09`09&x_output`09`09,`09`09`09/* Output string`09`09`09`09*/ X`09`09`09l_physical_pages`09,`09`09`09/* Number of enabled physical pages`09 V`09*/ X`09`09`09l_physical_pages >> 11`09,`09`09`09/* Enabled megabytes of physical V memory `09*/ X`09`09`092, &"00255075"`5B ((l_physical_pages >> 9) & 3) * 2 `5D ) )`09/* Fr Vactional part of Mb`09`09*/ X`09`7D X`09ss_check( LIB$PUT_OUTPUT( &x_output ) ) X X#define`09DIVISOR`09`09l_physical_pages`09`09`09`09/* percentages are WRT "p Vhysical_pages"`09`09*/ X#define`09FIDDLE_FACTOR`09(DIVISOR / 2)`09`09`09`09`09/* Fiddle factor to ro Vund up/down the %tages`09*/ X#define PERCENTAGE( value ) (((value) * 100 + FIDDLE_FACTOR) / DIVISOR)`09/* V Return percentage of "value" WRT "physical_pages" */ X X`09ss_check( LIB$SYS_FAO( X`09`09&x_format_2`09,`09`09`09`09`09/* Format control string`09`09`09*/ X`09`090`09`09,`09`09`09`09`09/* No resultant length`09`09`09`09*/ X`09`09&x_output`09,`09`09`09`09`09/* Output string`09`09`09`09*/ X`09`09l_physical_pages - l_free_pages - l_modified_pages,`09/* Inuse page co Vunt`09`09`09`09*/ X`09`09PERCENTAGE( l_physical_pages - l_free_pages - l_modified_pages ), X`09`09l_free_pages`09,`09`09`09`09`09/* Free page count`09`09`09`09*/ X`09`09PERCENTAGE( l_free_pages ), X`09`09l_modified_pages,`09`09`09`09`09/* Modified page count`09`09`09`09*/ X`09`09PERCENTAGE( l_modified_pages ), X`09`09l_bad_pages`09) )`09`09`09`09`09/* Count of bad pages`09`09`09`09*/ X`09ss_check( LIB$PUT_OUTPUT( &x_output ) ) X X`09ss_check( LIB$SYS_FAO( X`09`09&x_format_3`09,`09`09`09`09`09/* Format control string`09`09`09*/ X`09`090`09`09,`09`09`09`09`09/* No resultant length`09`09`09`09*/ X`09`09&x_output`09,`09`09`09`09`09/* Output string`09`09`09`09*/ X`09`09l_vms_pages`09,`09`09`09`09`09/* Pages in use by VMS`09`09`09`09*/ X`09`09PERCENTAGE( l_vms_pages ) ) ) X`09ss_check( LIB$PUT_OUTPUT( &x_output ) ) X X`09return SS$_NORMAL; X`7D X`0C X X/*************************************************************************** V********************************************** X X`09`09`09`09`09S I Z E _ M E M O R Y X X Calculate the amount of memory in use by this VMS system. X X `A9 1990 Nick de Smith and Applied Telematics Group Ltd. X This software is supplied for information only. No guarantee is supplied fo Vr this software, and no liability X will be accepted for any action resulting from the use of this software or V the information contained herein. X Under no circumstances may this software be used for commercial gain, inclu Vding its sale, lease or loan. X This software may be copied only with the inclusion of this copyright notic Ve. X The author is prepared to enter into correspondance with interested parties V, but will not necessarily X maintain this software. Having said all that, enjoy it! X X This code, I believe, is definitive. That is to say that it implements the V same algorithms as used by SHOW MEMORY, X which I presume to be correct. Hopefully my implementation of these algorit Vhms is correct, and so this will kill X another one of the perenial Info-VAX woolly arguments 8-). X X This is a "stand-alone" routine that can be called from any VMS language. I Vt must be called at EXEC mode or via a X SYS$CMEXEC call with an argument list. X The code in the routine is effectively a C representation of the DCL SHOW M VEMORY command. I acknowledge the use of X the VMS V5.3-1 fiche in determining the algorithms to use. X No scan is done of the bad page list as we do not need to differentiate bet Vween soft and hard memory errors - we just X take the total bad count. X A interesting feature of this routine is that it returns the "real_physical V_pages" (the number of pages of memory X physically in the machine) as well as "physical_pages" (the number of pages V that are enabled). This latter number will X always be less than or equal to the former. The reason for this is that the V SYSGEN parameter PHYSICALPAGES can be used X to artificially constrain a system to use less memory than there really is, V in order to test systems with differing X memory sizes without having to put in or haul out physical boards. As the r Voutine returns both values, it is possible X to check a) how much "real physical" memory there is actually on the system V, and b) how much of it VMS is allowed X to use. The DCL command SHOW MEMORY only displays the enabled memory. X This routine must be linked with SYS$SYSTEM:SYS.STB/Selective_Search. X X Edit`09Edit date`09By`09`09Why X 01`0920-Sep-90`09Nick de Smith`09First attempt - with thanks to the SHOW M VEMORY code. X X**************************************************************************** V*********************************************/ X Xglobalref unsigned long SCH$GL_FREECNT;`09`09`09`09`09/* Number of free page Vs`09`09`09`09*/ X#define`09PFN$C_BADPAGLST`090x2`09`09`09`09`09`09/* ...Offset to count of ba Vd pages in longwords`09*/ Xglobalref unsigned long SCH$GL_MFYCNT;`09`09`09`09`09/* Number of modified p Vages`09`09`09*/ Xglobalref unsigned long PFN$GL_PHYPGCNT;`09`09`09`09/* Physical pages for pr Vocess use`09`09*/ Xglobalref unsigned long MMG$GL_PHYPGCNT;`09`09`09`09/* Configured (SYSGEN) l Vimit on pages`09`09*/ Xglobalref unsigned char *EXE$GL_RPB;`09`09`09`09`09/* => Restart Parameter B Vlock`09`09`09*/ X X/* From $NDTDEF`09 - Nexus Device Type codes`09*/ X#define NDT$_MPM0`090x0040`09`09`09`09`09`09/* Multiport Memory 0`09`09`09`0 V9*/ X#define NDT$_MPM3`090x0043`09`09`09`09`09`09/* '' '' 3`09`09`09`0 V9*/ X X/* From $RPBDEF`09- Restart Parameter Block`09*/ X#define RPB$L_MEMDSC`090xBC`09`09`09`09`09`09/* Offset into RPB for memory d Vescriptors`09*/ X#define RPB$C_NMEMDSC`090x8`09`09`09`09`09`09/* Max. number of memory descri Vptor.`09`09*/ Xtypedef struct MEMDSC `7B X`09unsigned page_count`09: 24;`09`09`09`09/* Number of pages in this descrip Vtor`09*/ X`09unsigned tr_number`09: 8;`09`09`09`09/* Adaptor type number`09`09`09*/ X`09unsigned base_pfn`09: 32;`09`09`09`09/* Base PFN for this memory`09`09*/ X`7D MEMDSC, *MEMDSC_PTR; X X#define RPB$L_BOOTR5`090x30`09`09`09`09`09`09/* Offset into RPB copy of boot V time R5`09`09*/ X#define RPB$M_MPM`090x00000800`09`09`09`09`09/* Use MultiPortMemory only`09` V09`09*/ X#define RPB$M_USEMPM`090x00001000`09`09`09`09`09/* Use MultiPortMemory as we Vll as local memory`09*/ X X#define`09RPB$L_BADPGS`090x104`09`09`09`09`09`09/* Count of bad pages at boo Vt time`09`09*/ X Xunsigned long XSIZE_MEMORY( X`09unsigned long *`09al_physical_pages`09,`09`09`09/* => Returned physical p Vage count`09`09*/ X`09unsigned long *`09al_free_pages`09`09,`09`09`09/* => '' free ' V' ''`09`09*/ X`09unsigned long *`09al_modified_pages`09,`09`09`09/* => '' modified V '' ''`09`09*/ X`09unsigned long *`09al_vms_pages`09`09,`09`09`09/* Count of pages used by V VMS`09`09`09*/ X`09unsigned long *`09al_bad_pages`09`09,`09`09`09/* Count of bad pages`09`09 V`09`09*/ X`09unsigned long *`09al_real_physical_pages`09)`09`09`09/* "real" count of p Vhysical pages`09`09*/ X`7B X`09int`09`09l_local_pages, l_multiport_pages; X`09unsigned long`09l_nmemdsc = RPB$C_NMEMDSC;`09`09`09/* Maximum number of m Vemory descriptors`09`09*/ X`09MEMDSC_PTR`09ar_memdsc = EXE$GL_RPB + RPB$L_MEMDSC;`09`09/* => first memo Vry descriptor in RPB`09`09*/ X`09unsigned long`09l_boot_r5 = *((unsigned long *)(EXE$GL_RPB + RPB$L_BOOTR5 V)); /* Copy of system boot R5 value`09*/ X X`09*al_free_pages`09`09= SCH$GL_FREECNT;`09`09`09/* Return number of pages o Vn free list`09`09*/ X`09*al_modified_pages`09= SCH$GL_MFYCNT;`09`09`09/* '' '' '' '' ' V' modified list`09*/ X X`09l_local_pages = l_multiport_pages = 0; X X`09for ( ; ar_memdsc->page_count && l_nmemdsc-- ; ar_memdsc++ ) `7B`09/* Sca Vn each memory descriptor`09`09`09*/ X X`09`09/* If adapter is within MPM range, then its multiport memory. An assum Vption is made here that all memory X`09`09 with adaptor numbers in the range NDT$_MPM0 to NDT$_MPM3 is multipo Vrt memory, and that no multiport X`09`09 memory has an adaptor number outside of this range.`09`09`09`09`09` V09 `09*/ X X`09`09if ( ar_memdsc->tr_number >= NDT$_MPM0 && ar_memdsc->tr_number <= NDT$ V_MPM3 ) `7B X`09`09`09l_multiport_pages += ar_memdsc->page_count;`09/* Its a multiport me Vmory descriptor`09`09*/ X`09`09`7D else `7B X`09`09`09l_local_pages += ar_memdsc->page_count;`09`09/* Its local memory on Vly`09`09`09*/ X`09`09`7D X`09`7D X X`09/* Check the boot flags (/R5:xxxxxxxx) for the memory configuration (real Vly for 11/782s only)`09`09`09*/ X X`09if ( l_boot_r5 & RPB$M_MPM ) `7B`09`09`09`09`09/* If this is a multiproce Vssor configuration...`09*/ X`09`09*al_real_physical_pages = l_multiport_pages;`09`09/* ...then we are on Vly using shared memory`09*/ X`09`7D else `7B X`09`09*al_real_physical_pages = l_local_pages;`09`09/* The system is using t Vhe local memory.`09*/ X`09`09if ( l_boot_r5 & RPB$M_USEMPM ) `7B`09`09`09/* If USEMPM is set, we ar Ve using MPM as well... */ X`09`09`09*al_real_physical_pages += l_multiport_pages;`09/* ...so add in the V multiport memory pages`09*/ X`09`09`7D X`09`7D X X`09/* Check to see if the SYSGEN PHYSICALPAGES parameter has been used to li Vmit the usable number of pages`09`09*/ X X`09if ( *al_real_physical_pages <= MMG$GL_PHYPGCNT ) `7B`09`09/* If the phys Vical memory count is lower...`09*/ X`09`09*al_physical_pages = *al_real_physical_pages;`09`09/* ...than the maxi Vmum allowed by SYSGEN, use it */ X`09`7D else `7B X`09`09*al_physical_pages = MMG$GL_PHYPGCNT;`09`09`09/* Usable pages have bee Vn limited by SYSGEN`09*/ X`09`7D X`09*al_vms_pages = *al_physical_pages - PFN$GL_PHYPGCNT;`09`09/* Get pages u Vsed by VMS`09`09`09*/ X X`09*al_bad_pages = *((unsigned long *)(EXE$GL_RPB + RPB$L_BADPGS)); /* # of V bad pages at boot`09`09`09*/ X`09*al_bad_pages += *((unsigned long *)(&SCH$GL_FREECNT + PFN$C_BADPAGLST)); V /* # of bad pages since boot`09`09*/ X X`09*al_vms_pages -= *al_bad_pages;`09`09`09`09`09/* Don't count bad pages to V VMS`09`09`09*/ X X`09return SS$_NORMAL; X`7D $ CALL UNPACK SHOW_MEMORY.C;1 1195669633 $ v=f$verify(v) $ EXIT /* ---------- */