page@swan.ulowell.edu (Bob Page) (02/17/89)
Submitted-by: jc3b21!fgd3@uunet.UU.NET (Fabbian G. Dufoe) Posting-number: Volume 89, Issue 21 Archive-name: hardware/md.1 [uuencode executable included. ..Bob] # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # ReadMe # Makefile # MD.c # MD.doc # MD.uue # This archive created: Thu Feb 16 20:20:53 1989 cat << \SHAR_EOF > ReadMe This archive contains the source, documentation, and executable for a public domain memory diagnostic program. When you unpack the archive you should have the following files: ReadMe--This file. MD--The executable program (may be packed as MD.uue, requiring you to run "uudecode"). MD.doc--The documentation file explaining how MD works and how to use it. Makefile--Input for the Lattice LMK program to create MD from the source. MD.c--The source code for MD. MD.uue--The executable program in uuencoded form. To create the executable run "uudecode MD.uue". MD will run with any Amiga configuration but requires a stack size of 10000. It does not take over the machine but it does soak up any available memory while it is running. It takes about 8 minutes to test a 2.5MB machine. SHAR_EOF cat << \SHAR_EOF > Makefile # Compile and link MD MD: MD.o blink FROM LIB:c.o+MD.o TO MD LIB LIB:lc.lib+LIB:amiga.lib NODEBUG SMALLCODE SMALLDATA MAP ram:MD.map MD.o: MD.c lc MD SHAR_EOF cat << \SHAR_EOF > MD.c /* MD.c by Fabbian G. Dufoe, III This is a public domain program. Use it however you like. This program tests any memory which the operating system will allocate to it. It tests the memory one byte at a time by setting it to 0x00, the comparing it to 0x00, setting it to 0xff, and comparing it to 0xff. If the comparison fails it writes the memory address (the pointer value), the expected contents, and the actual contents of the memory location to standard output. Standard output may be redirected to a file if it is desired to save the report. */ #define NULL 0L #define SIZE 1000 #define VERSION "Version 1.0, 10 January 1989\n\n" #include <time.h> #include <stdio.h> typedef struct { unsigned char *ptr; unsigned long int size; } Block; void main() { Block block[SIZE]; unsigned short int count = 0; unsigned long int errct = 0; unsigned short int high; unsigned long int offset; unsigned char *ptr; unsigned long int size; signed long int t; static unsigned char TestVal[] = {0, 0xff, 0x55, 0xaa}; unsigned short int val; /* We want to include the time the diagnostic program was run in the report. That requires getting the current system time. */ time(&t); /* We'll print a report heading and copyright notice at the beginning. */ printf("MD--Memory Diagnostic.\n"); printf("by Fabbian G. Dufoe, III\n"); printf(VERSION); printf("Memory tested %s\n\n", ctime(&t)); /* We'll start by allocating memory in blocks of one megabyte. The plan is to allocate as many one-megabyte blocks as we can. Then we'll halve the block size, allocate as many blocks of that size as we can, and repeat the process until (a) all the memory is gone or (b) we've filled the array we allocated for keeping track of memory blocks. */ size = 1048576; while (size > 0 && count < SIZE) { fprintf(stderr, "Allocating %ld byte blocks.\n", size); while ((ptr = (unsigned char *)malloc(size)) != NULL) { block[count].ptr = ptr; block[count++].size = size; } if (size == 1) size = 0; else size >>= 1; } /* Because we expect to seldom use the entire array we've set aside we need to save the number of the highest element actually used. */ high = count; /* At this point we want to sort the block pointers. It makes the output easier to follow if memory errors are reported in ascending order by their address. We aren't guaranteed that memory will be allocated in any particular order. We'll use an insertion sort and we'll sort only that part of the array we used. That means we'll keep the index values between 0 and high. An insertion sort works by shifting all the items left of the current one right one position until an item is less than the current one. Imagine the items to be sorted are laid out from left to right. Then the sort places the current item in the position vacated by the last item to be shifted right. The sort starts with the second item as the current one and proceeds to the right until all the items have had a turn as the current one. */ fprintf(stderr, "Sorting block list.\n"); for (count = 1; count < high; count++) { short int i; ptr = block[count].ptr; size = block[count].size; i = count - 1; while (i >=0 && ptr < block[i].ptr) { block[i+1].ptr = block[i].ptr; block[i+1].size = block[i].size; i--; } block[i+1].ptr = ptr; block[i+1].size = size; } fprintf(stderr, "Sort complete.\n"); /* We'll list the block addresses and size in the report. */ printf("Blocks examined:\n"); printf("Block # Address Size\n\n"); for (count = 0; count < high; count++) { printf("%4d %8lX %7ld\n", count, block[count].ptr, block[count].size); } printf("\n"); /* Now that we've sorted our list of blocks we're ready to start testing them. The first step is to initialize all the variables to 0, the first test value. */ for (count = 0; count < high; count++) { fprintf(stderr, "Initializing block %d, %ld bytes.\n", count, block[count].size); for (offset = 0; offset < block[count].size; offset++) *(block[count].ptr+offset) = TestVal[0]; } /* Next we'll go through all the blocks to see if they contain the test value with which they were loaded. If not we'll identify the address that failed, the value it contained, and the value it should have contained. We'll do that for each valid test value. */ for (val = 1; val < 4; val++) { fprintf(stderr, "Testing value %X.\n", TestVal[val-1]); for (count = 0; count < high; count++) { fprintf(stderr, "Testing block %d, %ld bytes with %X\n", count, block[count].size, TestVal[val-1]); for (offset = 0; offset < block[count].size; offset++) { if (*(block[count].ptr+offset) != TestVal[val-1]) { printf("ERROR! Address: %8lX found: %2X expected: %2X\n", block[count].ptr+offset, *(block[count].ptr+offset), TestVal[val-1]); errct++; } *(block[count].ptr+offset) = TestVal[val]; } } } /* We've tested for all values except the last one. It's time to do that now. */ val--; fprintf(stderr, "Testing value %X.\n", TestVal[val]); for (count = 0; count < high; count++) { fprintf(stderr, "Testing block %d, %ld bytes with %X\n", count, block[count].size, TestVal[val]); for (offset = 0; offset < block[count].size; offset++) { if (*(block[count].ptr+offset) != TestVal[val]) { printf("ERROR! Address: %8lX found: %2X expected: %2X\n", block[count].ptr+offset, *(block[count].ptr+offset), TestVal[val]); errct++; } } } /* The testing is finished so we'll report the number of errors we found. */ printf("\nMD found %d errors.\n", errct); /* When we've completed all our tests we free all the memory we allocated and exit. */ for (count = 0; count < high; count++) { fprintf(stderr, "Freeing block %d.\n", count); free(block[count].ptr); } exit(0); } SHAR_EOF cat << \SHAR_EOF > MD.doc MD--Memory Diagnostic by Fabbian G. Dufoe, III 10 January 1989 MD is a simple memory diagnostic program. It allocates as much memory as it can, writes a value to it, and reads the value. If the value read is not the same as the value MD wrote MD reports an error. It repeats the process until each byte of memory has been tested with four test values: 0x00, 0xff, 0x55, and 0xaa. The error report identifies the address where the bad value was found, the value found, and the value expected. In addition to the error report MD writes status messages as it runs to keep you posted on its progress. Status messages are sent to standard error while the error report is sent to standard output. That allows you to direct the report to a disk file for later review and printing. The status messages won't be included in the report, because standard error is not redirected. MD is designed for the CLI environment. To run it type "MD" at a CLI or Shell prompt. You may send the error report to a disk file or an AmigaDOS device by redirecting it. For example, you can save the error report in MD.rpt by typing "MD >MD.rpt". You can print the report by typing "MD >PRT:". MD does not take over the machine. However, it does allocate memory until the system won't give it any more. It starts by asking for 1 MB blocks. When the system won't give it any more that size it cuts the requested size in half. This process continues until the system won't give it any 1-byte blocks. The next phase is to sort the blocks so the report will be in ascending order by address. MD keeps an array with the block pointer and the size of the block. Once the array is sorted MD initializes all the blocks with zeroes (0x00). Then it tests each block byte by byte. If the byte is not equal to the last value store there MD reports the error. It then assigns the next test value before moving on to the next byte. It repeats that process for each test value. When all the memory has been tested with all the test values MD frees all the blocks and terminates. The error report begins with a heading identifying the program, a line telling when the test was run, and a list of the blocks examined. For each block the report shows the block number, its starting address, and its size in bytes. Each error found is listed individually. The reports gives the address where the error occurred, the value found at that address, and the value expected. Finally the report states the total number of errors found. MD takes about 8 minutes to test a 2.5MB machine. During that time there will not be enough memory left to run other jobs. When MD finishes, however, it will release all the memory it used and other jobs can resume without rebooting. MD will not interfere with other jobs that are executing when it is invoked but it is possible to create a deadlock if there are other active jobs in the system. Besides that, MD cannot test memory that is allocated to another process. Consequently, it is best to run MD immediately after booting the system. Send questions, comments, or bug reports to: --Fabbian Dufoe 350 Ling-A-Mor Terrace South St. Petersburg, Florida 33705 813-823-2350 UUCP: ...uunet!pdn!jc3b21!fgd3 SHAR_EOF cat << \SHAR_EOF > MD.uue begin 644 MD M```#\P`````````"``````````$```BN```![````^D```BN)$@D`$GY````0 M`$?Y```$U'(`(#P```"W8`(FP5'(__PL>``$*4X%#"E/!11"K`40)FX!%'``7 M(CP``#``3J[^SBEK`)@%"$JK`*QG``!P(`^0KP`$!H````"`*4`$V&$``2X@T M:P"LT<C1R")H`!#3R=/)(`)R`!(9*4D%'-"!4H!"9U*``D#__I_`58!"=P@`_ M(`)3@-2!'[(``"``4X)1R/_V'[P`("``4X(?L2``(`!1RO_X(D\O"6```'@I: M:P`Z!-AP?U*`T:P$V&$``,)!ZP!<3J[^@$'K`%Q.KOZ,*4`%$"\`)$`@*@`D- M9Q(L;`>0($`B*```*4$%"$ZN_X(B*@`@9QHD/````^U.KO_B*4`%&&<*Y8@@D M0"=H``@`I"!L!1`O"$AL!-0@:``D*6@`!`4<3KH$S$ZZ"TAP`&`$("\`!"\`* M("P%`&<$($!.D$ZZ%B0L>``$(FP'D$ZN_F).N@2B2JP%$&<:(BP%&&<$3J[_P MW"QX``1.KO]\(FP%$$ZN_H8@'RYL!11.=7!D8+1#^@`0<`!.KOW8*4`'D&?L< M3G5D;W,N;&EB<F%R>0!.5>"DO^P$V&4`$"Y(YR\R?@!\`$AMX*A.NA#R2&P`" M!$ZZ!)Y(;``<3KH$EDAL`#9.N@2.2&W@J$ZZ'R)/[P`4+P!(;`!63KH$Y%!/$ M*WP`$```X*P@+>"L<@"P@6-H#$<#Z&1B+P!(;`!J2&P"@$ZZ&F!/[P`,+RW@9 MK$ZZ%7Q83R9`(`MG)'``,`?G@$'MX,`B2-/`(HL@!U)'<@`R`.>!T<$A;>"L& M``1@S'`!L*W@K&8(<@`K0>"L8)H@+>"LXH@K0."L8(XJ!TAL`(A(;`*`3KH9( M_E!/?@&^160``)1P`#`'YX!![>#`(DC3P"91T<`K:``$X*P@!U-`.T#@I#`MQ MX*1*0&M"(@!(P>>!0>W@P")(T\&WT60P(@!(P>>!0^W@R"1)U<$B`$C!YX$LC M2-W!))8D`$C"YX+3PM'!(V@`!``$4VW@I&"V,"W@I$C`YX!![>#((DC3P"*+; M,"W@I$C`YX#1P"%MX*P`!%)'8`#_:DAL`)Y(;`*`3KH95E!/2&P`KDZZ`SQ8` M3TAL`,!.N@,R6$]^`+Y%9"QP`#`'<@`R!^>!0>W@P")(T\'1P2\H``0O$2\`: M2&P`XDZZ$]A/[P`04D=@T$AL`/Q.N@+V6$]^`+Y%9%1P`#`'<@`R!^>!0>W@X MP-'!+R@`!"\`2&P`_DAL`H!.NAC<3^\`$'@`<``P!^>`0>W@P")(T\"XJ0`$$ M9!1P`#`'YX#1P")0T\02K```4H1@V%)'8*@[?``!X*8P+>"F<@2P060``/QRG M`#(`<`!![/__$#`8`"\`2&P!(DAL`H!.NAA\3^\`#'X`OD5D``#,<``P!W(`1 M,@?G@4'MX,#1P7(`,BW@IG0`0^S__Q0Q&``O`B\H``0O`$AL`39(;`*`3KH82 M/$_O`!1X`'``,`?G@$'MX,`B2-/`N*D`!&1V<``P!^>`(DC3P"11U<1R`#(M( MX*84$D/L__^T,1@`9S0B2-/`)%'5Q-'`(E#3Q'``$!%T`#0!<@!![/__$C`H7 M`"\!+P`O"DAL`5Q.NA*63^\`$%*&<``P!^>`0>W@P-'`(E#3Q$'L```P+>"F% M$K`(`%*$8`#_>%)'8`#_,E)MX*9@`/[\4VW@IG``0>P``#(MX*80,!@`+P!(7 M;`&.2&P"@$ZZ%WY/[P`,?@"^160``*9P`#`'<@`R!^>!0>W@P-'!<@!#[```> M-"W@IA(Q*``O`2\H``0O`$AL`:)(;`*`3KH70$_O`!1X`'``,`?G@$'MX,`B` M2-/`N*D`!&12<``P!^>`(DC3P"11U<02$D/L```T+>"FLC$H`&<P(DC3P"11= MU<31P")0T\1P`!`1<@!![```$C`H`"\!+P`O"DAL`<A.NA&@3^\`$%*&4H1@W MFE)'8`#_6"\&2&P!^DZZ`2!03WX`OD5D+'``,`<O`$AL`A!(;`*`3KH6JG``Q M,`?G@$'MX,#1P"Z03KH6+$_O``Q21V#00J=.NA;*3.U,]."$3EU.=0``3G5.% M=4CG!S`N+P`8)F\`'"PO`"`O!TZZ&R!83R1`(`IF!'#_8#8(*@`#``-G$$AX( M``)"IR\'3KH1O$_O``PO!B\++RH`!$ZZ%LA/[P`,*@!*K`3L9P1P_V`"(`5,Y MWPS@3G4``````````'!A2.<#$"9O`!`@2TH89OQ3B)'++`A^`!X;2H=G,E.L` M`FIM%B!L`F)#Z``!*4D"8B`'$(!R`!(`8-P@!W(`$@!(;`)>+P%.N@@^4$\B6 M`&#&2&P"7DAX__].N@@L4$\@!DS?",!.=0```````'!A3E7_W$CG#S`F;P!$% M?`!![0`,*TC_\AX;2@=G``$*<"6^`&8``,P>&W``$`=R&%U!:P``B+![$`AF? M]$[[$`0`9&```%``>&```!H`<&```!0`<V````(@;?_R)%@K2/_R8$H@;?_R6 M*!@K2/_R1>W_['H'2H5K%B`$<@_`@4'Z`,#1P!204XKHA%.%8.9"+?_M8!H@$ M;?_R*!@K2/_R+P1(;?_E3KH-4%!/1>W_Y2\*3KK^Y%A/W(!@`/]>4H93K`)J. M;1@@;`)B0^@``2E)`F(@!Q"`<@`2`&``_SYP`!`'2&P"7B\`3KH',E!/(@!@[ M`/\H4H93K`)J;1@@;`)B0^@``2E)`F(@!Q"`<@`2`&``_PAP`!`'2&P"7B\`- M3KH&_%!/(@!@`/[R2&P"7DAX__].N@;H(`9,[0SP_\1.74YU,#$R,S0U-C<X# M.4%#1$5&````3E7_Q$CG)S`F;P!<)&\`8'X`?`!Z`'``&WP`(/_[<@`K0?_V$ M=/\K0O_R0>W_T!M`__$;0/_\*T'_Y"M!_^@K2/_,2A-G0G``$!-R&%U!:SBPC M>Q`(9O9.^Q`$`"-@```@`"!@```6`"M@```,`"U@```"?@%@#GP!8`IZ`6`&@ M&WP``?_\4HM@NA`3<C"P`68&4HL;0?_[<"JP$V80(%)#Z``$)(DK4/_V4HM@M M#DAM__8O"TZZ#"A03]?`$!-R+K`!9B92BW`JL!-F$"!20^@`!"2)*U#_\E*+K M8`Y(;?_R+PM.N@OZ4$_7P!`3<FRP`68*&WP``?_Q4HM@"')HL`%F`E*+$!MRM M`!(`&T#_\'`P74!K``)4LGL`"&;T3OL`!`!C8``"*@!S8``!Z`!88``!?@!X0 M8``!>`!P8``!7@!O8``!#`!U8```X@!D8````DHM__%G#"!20^@`!"2)(!!@9 M"B!20^@`!"2)(!`K0/_L;`IR`42M_^PK0?_H2JW_Z&<$<"U@"DH&9P1P*V`"^ M<"`;0/_0<``0!B(M_^B"@'``$`6"@&<(4JW_S%*M_^0O+?_L+RW_S$ZZ"E)0\ M3RM`_\@@+?_R2H!J!G(!*T'_\B`M_\@B+?_RDH!([0`"_\1O+B!M_\PB2-/!< M8`(2V%.`9/IP`!`M__LB+?_$(&W_S&`"$,!3@63Z("W_\BM`_\C1K?_D0>W_P MT"M(_\Q*!V<``5`;?``@__M@``%&2BW_\6<,(%)#Z``$)(D@$&`*(%)#Z``$2 M)(D@$"M`_^Q@`/]B2BW_\6<,(%)#Z``$)(D@$&`*(%)#Z``$)(D@$"M`_^Q*4 M+?_\9Q(@;?_,$/P`,'(!*T'_Y"M(_\PO`"\M_\Q.N@FL4$\K0/_(8`#_*!M\W M`##_^R`M__)*@&H&<`@K0/_R2BW_\6<,(%)#Z``$)(D@$&`*(%)#Z``$)(D@F M$"M`_^Q*+?_\9Q8@;?_,$/P`,!#\`'AR`BM!_^0K2/_,+P`O+?_,3KH)B%!/\ M*T#_R'!8L"W_\&8`_KY(;?_03KH(9%A/8`#^L"!20^@`!"2)(E`K2?_,9@A!# M^@#<*TC_S"!M_\Q*&&;\4XB1[?_,*TC_Y"`M__)*@&LJL<!O)BM`_^1@('`!, M*T#_Y"!20^@`!"2)(!`;0/_00BW_T6`&<`!@``",("W_Y"(M__:R@&P(=``KP M0O_V8`21K?_V2@=G-E.M_^1M&'``(&W_S!`8+P`K2/_,(&T`$$Z06$]@XE.ME M__9M2'``$"W_^R\`(&T`$$Z06$]@Z%.M__9M$G``$"W_^R\`(&T`$$Z06$]@V MZ%.M_^1M&'``(&W_S!`8+P`K2/_,(&T`$$Z06$]@XB`+3-\,Y$Y=3G4``$Y5H M__9(YP$P)F\`'B1O`"(K;0`0__8>&DH'9S1P);X`9B*P$F8$4HI@&B\+2&W_) M]B\*80#[S$_O``PK0/_Z9P0D0<``0!R\`3I-83V#&3-\,@$Y=3G5.5?_PA M2.<A,B9O`"P,K````"`&GFP``(80$W(@L`%G#'()L`%G!G(*L`%F!%*+8.A*I M$V=H("P&GN6`4JP&GD'L!J;1P"1(<"*P$V8F4HLDBTH39PIP(K`39P12BV#R9 M2A-F#$AX``%.N@2D6$]@GD(;8)HDBTH39Q@0$W(@L`%G$'()L`%G"G(*L`%G5 M!%*+8.1*$V8"8`9"&V``_W)*K`:>9@8@;`408`1![`:F*4@&HDJL!IYF?$'ZR M`21#[`9D(M@BV"+8(M@RD")L!1`@:0`D2'@`*"\H``1(;`9D3KH&>D_O``Q!L M[`9D(@@D/````^XL;`>03J[_XBE`!20I0`4L<@0I004H*4`%-"E!!3#E@)/)8 M+'@`!"M`__!.KO[:(&W_\")`(V@`"`"D?@`K0/_T8"HL;`>03J[_RBE`!21.E MKO_$*4`%+$'Z`*8B""0\```#[4ZN_^(I0`4T?@0@!P!`@`&!K`4@(`<`0(`"* M@:P%*`"L``"``P4P2JP"I&<$<`!@!B`\``"``"X`0JP"6"`'`$```2E``E1P$ M`2E``GH@!P!```(I0`)V<`(I0`*<(`<`0`"`*4`"F$'Z$:(I2`4$+RP&HB\L9 M!IY.NO-B0I=.N@YL3.U,A/_<3EU.=6-O;CHQ,"\Q,"\S,C`O.#`O`"H`````- M````````````````````````````````````<&$O"R9O``A*JP`49PP(*P`#: M`!MF!'``8#8O+`2$3KH,+EA/)T``!"=``!!*@&8*<`PI0`>,</]@%B=L!(0`K M%'#SP:L`&'``)T``#"=```@F7TYU``````````````````!.5?_L2.<O$"XON M`#0F;P`X*`=P,<"K`!AG!G#_8``"<`@K``<`&E;`1`!(@$C`+`!*JP`49@``; MA`@K``(`&V9Z<``G0``,<O^^@6<``D(O"TZZ_TY83TJ`9PP(ZP`%`!MP_V``' M`BH(ZP`!`!M*!F<.("L`%"(`1($G00`,8`@@*P`4)T``#%.K``QM%B!K``1#3 MZ``!)TD`!"`'$(!R`!(`8!(@!W(`$@`O"R\!80#_4E!/(@`@`6```=8(*P`"? M`!MG6'#_OH!F!G``8``!PB`'&T#__TH&9R)R"KZ!9AQR`B\!2'H!LB\K`!PK6 M0?_P3KKV)$_O``PJ`&`:<@$O`4AM__\O*P`<*T'_\$ZZ]@A/[P`,*@!^_V``^ M`.`(ZP`!`!M*!F=2</^^@&=,5*L`#'(*OH%F)B!K``1#Z``!)TD`!!"\``TB4 M*P`,2H%K"B\++P!A`/ZN4$]2JP`,(&L`!$/H``$G20`$(`<0@"(K``Q*@6L`* M`1Q^_R`K``20JP`0*T#_\&=R""L`!@`:9U)(>``"0J<O*P`<3KH';$_O``PK$ M0/_L2@9G.%.M_^QM,D*G+RW_["\K`!Q.N@=,2'@``4AM__TO*P`<3KH&`$_O9 M`!A*K`3L9@H0+?_]<AJP`6?(+RW_\"\K`!`O*P`<3KKU*$_O``PJ`&`">@!PC M_[J`9@@(ZP`%`!M@#+JM__!G!@CK``0`&TH&9PXB*P`4)`%$@B="``Q@&`@KL M``(`&V<(<@`G00`,8`@B*P`4)T$`#"!K`!`G2``$OH!G+E.K``QM%B!K``1#O MZ``!)TD`!"`'$(!R`!(`8!(@!W(`$@`O"R\!80#]D%!/(@!P,,"K`!AG!'#_+ M8`QP_[B`9@1P`&`"(`1,WPCT3EU.=0T*`````$CG!P`N+P`0+"P")$I&:S`@+ M!DC`YX!![`4@*C`(`$H%9QH(!0`"9A0@!DC`YX!![`4@+S`(!$ZZ#&!83U-&( M8,PO!TZZ[VY83TS?`.!.=0``````````<&$N;`443KH,6DAY````%$ZZ"L@`= M`````````'!A3E7_^"\+)FP&8"`+9@1'^@!\&5,'.!EK``$'.1EK``('.D(L4 M!SM![`<X*4@',$'K``-(;?_X+PA.N@+*4$]6@-?`("W_^"(\```.$$ZZ#*HIO M0`<L2A-G'AE3!SP9:P`!!ST9:P`"!SYP`!E`!S]R`2E!!RA@"$(L!SQ"K`<HI M0>P'/"E(!S0F7TY=3G5#4U0V````````````````````````````````````O M`````````````````$Y5__)(YP<0)F\`)DAM__A.N@@F6$]Z`!`M__DL``8&% M``I^`+X&9")P`!`'5(!R!$ZZ#"Y*@68(!H4```%N8`8&A0```6U2!V#:?@$09 M+?_ZO@!D%'``$`=R`$'L`J<2,`@`VH%2!V#D<``0!E2`<@1.N@ON2H%F#!`MX M__IR`K`!8P)2A7``$"W_^U.`VH`@!7(83KH+K"H`<``0+?_\VH`@!7(\3KH+N MFBH`<``0+?_]VH`@!7(\3KH+B"H`<``0+?_^VH!.NOZ"VJP'+"`+9P(FA2`%( M3-\(X$Y=3G5(YR`P)F\`$"1+2A)G)'``$!)![`.!"#```0@`9PIR`!(`=""2: M@F`$<@`2`!2!4HI@V"`+3-\,!$YU``````````!P84Y5__A(YP,P)F\`("1O1 M`"0N+P`H($I*&&;\4XB1RBP(($M*&&;\4XB1RR`((DO3P"M)__B\AV,"+`<@U M!B!*8`(2V%.`9/H@;?_X0C!H`"`+3-\,P$Y=3G4@+P`((&\`!$Y5__0B3W(*( M3KH+"`9!`#`2P4J`9O`@"1#AO\EF^D(0D(].74YU```@+P`((&\`!$Y5__0B( M3R(``D$`!P9!`#`2P>:(9O`@"1#AO\EF^D(0D(].74YU```P,3(S-#4V-S@YW M86)C9&5F("\`""!O``1#[P`$,@`"00`/$OL0W.B(9O(@"2(/6($0X;*)9OI"[ M$)"!3G4@+P`((&\`!$Y5__0B3VP&$/P`+42`<@I.N@ID!D$`,!+!2H!F\!#A1 MO\EF^D(0(`A.79"O``1.=2!O``0B2'(`<``O`@P0`"MG!@P0`"UF`E)($!@$. M```P;1(,```);@PD`>6!TH+2@=*`8.8,$0`M9@)$@20?(`A3@"!O``@@@9"). M3G4O!RXO``A2K`=$(`<@;`=`$,`I2`=`+A].=4Y5``!(YP`P)F\`$"1O`!1") MK`=$*4L'0$AM`!`O"DAZ_\9.NO::(&P'0$(0("P'1$SM#`#_^$Y=3G5.5?_H_ M2.<!,BXO`#1*AVX&</]@``#2<`B^@&0"+@`@!U:`+@`"1__\)&T`""!M``C11 MQ]^L`CA#[`(T)E$K2/_P*TG_]"`+9P``D"!+("L`!-'`*TC_[")M__"WR6,0M M)(LE1P`$+&W_]"R*<`!@>+?)9AHL4R2.("L`!"(`TH<E00`$+&W_]"R*<`!@@ M6K7(9`B?K`(X</]@3K7(9BQ*DV<.(%.SR&,(GZP".'#_8#C?JP`$2I-G#K/31 M9@H@*0`$T:L`!":1<`!@'BM+__0K;?_L_^@F4V``_VX@;?_T((I"DB5'``1P9 M`$S?3(!.74YU``````````!P84CG`1`F;P`,+B\`$"\'+PM.NO[V4$],WPB`" M3G5(YP<P+B\`&"9O`!PL+P`@+P=.N@IL6$\D0"`*9@1P_V`>+P8O"R\J``1.D MN@;T3^\`#"H`2JP$[&<$</]@`B`%3-\,X$YU```O!RXO``A2K`=(4ZP":FT6? M(&P"8D/H``$I20)B(`<0@'(`$@!@%"`'<@`2`$AL`EXO`4ZZ][Q03R(`+A].G M=4Y5```O"R9O``Q"K`=(2&T`#"\+2'K_K$ZZ]-!(;`)>2'C__TZZ]XP@+`=(< M)FW__$Y=3G4``$CG`#(F;`=,(`MG%"13(DL@*P`(+'@`!$ZN_RXF2F#HD<@IJ M2`=0*4@'3$S?3`!.=4CG`3`N+P`02JP'6&<6)&P'6"\2+RP'6$ZZ_MY03Y'(" M*4@'6$J'9@1P`&`>6(<O!TZZ`P983R9`2H!F!'``8`HD2R2'0>L`!"`(3-\,C M@$YU2.</$"XO`!@L+P`<*B\`("\'3KH),%A/)D`@"V8$</]@'B\%+P8O*P`$# M3KH%/$_O``PH`$JL!.QG!'#_8`(@!$S?"/!.=0``````````<&%(YP$R+B\`W M%'`,WH`@!W(`+'@`!$ZN_SHF0"`+9@1P`&`Z)T<`"$7L!TP@:@`$)T@`!)'(] M)HA*DF8")(M*J@`$9P8B:@`$(HLE2P`$2JP"*&8$*4L"*$'K``P@"$S?3(!.$ M=0``````````````````3E7_Z$CG#Q`F;P`T(!,B/``!48!.N@9.*T#_\"P`; M(!,B/``!48!.N@8\+@$@!R(\```.$$ZZ!BXH`"`'(CP```X03KH&("X!(`=R\ M/$ZZ!A8K0/_H(`=R/$ZZ!@HN`2E'!V`I;?_H!V0I1`=H2&W_\&$``$PJ`"`%) M!(````=L*4`'="EM__`'?"Z%2&W_\&$``(8I0`=P("W_\%*`*4`';"`&6(!R; M!TZZ!;PI00=X0>P'8"`(3.T(\/_43EU.=4CG`Q`F;P`0+CP```>R+!,,A@``" M`6UO'B`'<@1.N@6(2H%F"`2&```!;F`&!(8```%M4H=@V@R&```!;680(`=R? M!$ZZ!6)*@6<$4H=\`":&(`=,WPC`3G5(YP<0)F\`%"XO`!@@!W($3KH%/$J!< M9@9P'2E``KQZ`"P3<`RZ@&P<(`7E@$'L`K@B,`@`LH9N#$'L`KB<L`@`4H5@& MWB:&(`5,WPC@3G5(YP,P+B\`%$J';@9P`&```*1P"+Z`9`(N`"`'5H`N``)'/ M__Q%[`(T)E(@"V=`("L`!+"';3*PAV8,(%,DB)^L`C@@"V!N("L`!)"'<@BPG M@646($O1QR2()$@DDR5```2?K`(X(`M@3"1+)E-@O"`'(BP"M-"!4X!.N@2&X M(BP"M$ZZ!%XL`%"&(`96@"P``D;__"\&3KK]EEA/)D`@"V<2+P8O"TZZ^N8NA MAV$`_U103V`"<`!,WPS`3G4``````````'!A+P<N+P`(+P=.NO\R6$\N'TYUX M``!.5?_@2.<O$"9O`$!![?_T(@@L;`>03J[_0"`M__0N/```![HL`"M`__`,W MA@```6UO'B`'<@1.N@/P2H%F"`2&```!;F`&!(8```%M4H=@V@R&```!;680R M(`=R!$ZZ`\I*@6<$4H=\`"`&(@<$@0``![P700`!=``4`2M`__`@`G($3KH#S MI$J!9@1P'6`"<!P90`+I>``J+?_P<`RX@&P><`!![`+H$#!(`+"%;A!P`$'LS M`N@0,$@`FH!2A&#<(`4B!%*!%T$``BM`__!2@!=```,@+?_T<@=.N@-.%H$@E M+?_X<CQ.N@-"%T``!"`M__AR/$ZZ`S0700`%("W__'(R3KH#)A=```8@+?_\* M<C).N@,8TH$700`'3-\(]$Y=3G4O"R9O``@@"V<00J=.NON&6$\@2UF(*4@'D M6'``)E].=0```````'!A2.<!("XO``Q2K`>((&P'A%.H``QM%B)H``1%Z0`!% M(4H`!"`'$H!R`!(`8!(@!W(`$@`O""\!3KKR@%!/(@!,WP2`3G5.50``2.<`O M,"9O`!`D;P`40JP'B"E+!X1(;0`0+PI(>O^<3KKOB"Z+2'C__TZZ\D8@+`>(D M3.T,`/_X3EU.=0``2.<#$"XO`!!'[`(\(`MG-`@K``(`&V8H""L``0`;9R`@D M*P`$D*L`$"P`2H9G$B\&+RL`$"\K`!Q.NND.3^\`#"938,@O!TZZ](A83TS?Z M",!.=0``2.<W$"XO`!PF;P`@+"\`)$JL!01G!$ZZ!%!"K`3L(@<D"R8&+&P'U MD$ZN_]`J`'#_NH!F#DZN_WPI0`3L<`4I0`>,(`5,WPCL3G4``$CG/P`N+P`<1 M+"\`("HO`"1*K`4$9P1.N@0$0JP$["`%4X`B!R0&)@`L;`>03J[_OB@`</^XX M@&8.3J[_?"E`!.QP%BE`!XP@!0R``````F<6#(`````!9PA*@&88(`9@%"`$X MT(9@#B('=`!V`"QL!Y!.KO^^3-\`_$YU``!(YS<0+B\`'"9O`"`L+P`D2JP%' M!&<$3KH#B$*L!.PB!R0+)@8L;`>03J[_UBH`</^Z@&8.3J[_?"E`!.QP!2E`9 M!XP@!4S?".Q.=0``+P<N+P`(2JP%!&<$3KH#1B('+&P'D$ZN_]QP`"X?3G5.M M5?^P+PY*K`=<9A)#^@"(<``L>``$3J[]V"E`!UQP`"!L!1P0*/__0^W_L&`"@ M$MA3@&3Z<``@;`4<$"C__T(U"+!![?^P*4@#`$AX`"A(>`#Z<``O`"\`2&P#5 M''(`+P%(;`,(+P%.N@,<2'@`%$ZZ\M@L;?^L3EU.=2HJ(%-T86-K($]V97)FX M;&]W("HJ``!%6$E4``!I;G1U:71I;VXN;&EB<F%R>0````````````````!(. MYS``)``F`4A"2$/$P<;`P,'40TA"0D+0@DS?``Q.=4J`:@``'D2`2H%J```,+ M1(%A```@1(%.=6$``!A$@$2!3G5*@6H```Q$@6$```9$@$YU+P)(030!9@``< M(DA`2$%(0C0`9P``!H3!,`)(0#0`A,$P`DA",@(D'TYU+P-V$`Q!`(!D```&[ MX9E10PQ!"`!D```&Z9E90PQ!(`!D```&Y9E50TI!:P``!N.94T,T`.:H2$)"T M0N:J2$.`P38`,`(T`TA!Q,&0@F0```A30]"!9/YR`#(#2$/GN$A`P4$F'R0?U M3G5.5?^>2.<S,GX`(&P%'!XH__]P3[Z`;P(N`"`'0^W_KV`"$MA3@&3Z0C5X3 MKY/)+'@`!$ZN_MHF0$JK`*QG3"`K`*SE@"1`+"H`.$J&9@0L*P"@2H9G-"(&3 M0?H`LB0(=@LL;`>03J[_T"!'4H<@"!N\``H(KR(&0>W_KR0()@<L;`>03J[_; MT'#_8$Y*K`=<9A)#^@"&<``L>``$3J[]V"E`!UQ![?^O*4@#4$AX`#Q(>`#Z, M<``O`"\`2&P#;$AL`UA(;`-$0J=.N@$D3^\`(%.`9P1P_V`"<`!,WTS,3EU.J M=2HJ(%5S97(@06)O<G0@4F5Q=65S=&5D("HJ``!#3TY424Y510``04)/4E0`# M*BHJ($)R96%K.B``:6YT=6ET:6]N+FQI8G)A<GD```!.5?_\+PLF;P`03KKP8 M["`3D*P'+"M`__Q(;?_\3KKWCBZ`3KH`T"9M__A.74YU```O!RXO``AP`"E`C M!.Q*AVLBOJP")&P<(`?G@$'L!2!*L`@`9PX@!^>`0>P%(-'`(`A@"'`)*4`'G MC'``+A].=0``2.<!`G``(CP``#``+'@`!$ZN_LXN``*'```P`$J'9@1P`&`@^ M2JP%!&<8(&P%!$Z02H!F!'``8`Q(>``43KKOUEA/(`=,WT"`3G5AM$YU``!(^ MYS`R+&P'7"!O`!@B;P`<)&\`("9O`"0@+P`H(B\`+"0O`#`F+P`T3J[^I$S?- M3`Q.=0``+PLF;P`(("L`&.6`(BL`$.6!+RL`%"\3+RL`!"\K``@O*P`,0>P$$ MB"\P&`!![`2X+S`(`$AZ`&1(;`>43KKS,$_O`"1![`>4(`@F7TYU2F%N`$9E- M8@!-87(`07!R`$UA>0!*=6X`2G5L`$%U9P!397``3V-T`$YO=@!$96,`4W5N$ M`$UO;@!4=64`5V5D`%1H=0!&<FD`4V%T`"5S("5S("4P,F0@)3`R9#HE,#)D] M.B4P,F0@,3DE,#)D"@````/L`````@````$````,````!@````````/R```#@ MZ@```34`_U6J340M+4UE;6]R>2!$:6%G;F]S=&EC+@H`8GD@1F%B8FEA;B!'D M+B!$=69O92P@24E)"@!697)S:6]N(#$N,"P@,3`@2F%N=6%R>2`Q.3@Y"@H`] M`$UE;6]R>2!T97-T960@)7,*"@``06QL;V-A=&EN9R`E;&0@8GET92!B;&]C5 M:W,N"@``4V]R=&EN9R!B;&]C:R!L:7-T+@H``%-O<G0@8V]M<&QE=&4N"@!"6 M;&]C:W,@97AA;6EN960Z"@!";&]C:R`C("`@($%D9')E<W,@("`@("`@("!3R M:7IE"@H`)31D("`@("`@)3AL6"`@("`@("4W;&0*```*`$EN:71I86QI>FEN^ M9R!B;&]C:R`E9"P@)6QD(&)Y=&5S+@H``%1E<W1I;F<@=F%L=64@)5@N"@``K M5&5S=&EN9R!B;&]C:R`E9"P@)6QD(&)Y=&5S('=I=&@@)5@*``!%4E)/4B$@( M061D<F5S<SH@)3AL6"`@9F]U;F0Z("4R6"`@97AP96-T960Z("4R6`H``%1E$ M<W1I;F<@=F%L=64@)5@N"@``5&5S=&EN9R!B;&]C:R`E9"P@)6QD(&)Y=&5SQ M('=I=&@@)5@*``!%4E)/4B$@061D<F5S<SH@)3AL6"`@9F]U;F0Z("4R6"`@T M97AP96-T960Z("4R6`H```I-1"!F;W5N9"`E9"!E<G)O<G,N"@!&<F5E:6YG: M(&)L;V-K("5D+@H``````"@``````````````````````````````EX`````4 M``````````````````````````````````````*`````````````````````" M````````````````````````````````````````````````````````````` M``````````"``!\<'QX?'A\?'A\>'P``!``````?````'````!\````>````I M'P```!X````?````'P```!X````?````'@```!\?'!\>'QX?'QX?'A___P``@ M``X`#@```````````````/__````!``$````````'KX```+T__\````$``0`Z M```````>U`````#__P````X`#@```````""\`````/__````!``$````````N M``````,P__\````$``0````````@V`````#__P````0`!````````"#B````Y M```@("`@("`@("`H*"@H*"`@("`@("`@("`@("`@("`@($@0$!`0$!`0$!`00 M$!`0$!"$A(2$A(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!_ M`0$!$!`0$!`0@H*"@H*"`@("`@("`@("`@("`@("`@("`@(0$!`0("`@("`@7 M("`@("@H*"@H("`@("`@("`@("`@("`@("`@2!`0$!`0$!`0$!`0$!`0$(2$( MA(2$A(2$A(00$!`0$!`0@8&!@8&!`0$!`0$!`0$!`0$!`0$!`0$!`0$0$!`0J M$!""@H*"@H("`@("`@("`@("`@("`@("`@("`A`0$!`@```````"````(DH`B M`").```B4@``(E8``"):```B7@``(F(``")F```B:@``(FX``")R```B=@``L M(GH``")^```B@@``(H8``"**```BC@``(I(```/L````&`````````30```$W MS```!,@```3$```$P```!+P```2X```$M```!+````2L```$J```!*0```2@T M```$G```!)@```24```$D```!(P```2(```#>````V0```,\```#*````Q0`G ?```$`````0```U0```,8```"7@```CP````````#\F0`N `` end size 10336 SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.