(* * * * * * * * * * * * * * * * * * *
 *
 * prog2-2.pas
 *
 * Further demonstration of
 *    getMcbPointer(...)
 *
 * * * * * * * * * * * * * * * * * * *)

program prog2_2;

uses    _globals,
        _mcb;


var
    mcbPtr:             MCB_McbPtr;
    env:                CharPtr;
    envSeg:             Word;
    temp:               WordPtr;
    i:                  Word;

begin

    (*
     *  Get pointer to the first MCB
     *)
    mcbPtr:= getMcbPointer;

    (*
     *  Print the header
     *)
    writeln;
    writeln('Bax Boy''s Memory Display Program (Rev .2)');
    writeln;
    writeln(' PSP   SIZE     PROGRAM   ');
    writeln('----- ------  ----------- ');


    (*
     *  Loop over the MCB's printing out the info
     *)
    while True do begin

        (*
         *  Print the easy stuff
         *)
        write(hex(mcbPtr^.owner_psp, 4), '  ',
              (DWord(mcbPtr^.size_paragraphs) shl 4):6, '   ');

        (*
         *  If the PSP for this MCB is 0 then it represents
         *  free memory
         *)
        if mcbPtr^.owner_psp = 0 then begin
            write('(free mem)');
            end

        (*
         *  If the PSP is 8 then print config
         *)
        else if mcbPtr^.owner_psp = $08 then begin
                write('config');
                end

        (*
         *  Otherwise it's a program, so print the program name
         *)
        else begin
            (*
             *  Get environment segment pointer
             *)
            temp:= WordPtr(Ptr(mcbPtr^.owner_psp, $2c));

            (*
             *  Get program environment segment
             *)
            envseg:= temp^;

            (*
             *  Set pointer to environment
             *)
            env:= Ptr(envseg,0);

            (*
             *  Search environment for the program name
             *
             *  Scan to the double delimiter.
             *)
            while (env^ <> Chr(0)) or (CharPtr(DWord(env)+1)^ <> Chr(0)) do begin
                env:= CharPtr(DWord(env)+1);
                end;

            (*
             *  Skip the double delimiter:
             *)
            env:= CharPtr(DWord(env)+2);

            (*
             *  Search for executable filename.
             *)
            while env^ <> '.' do begin
                env:= CharPtr(DWord(env)+1);
                end;

            (*
             *  Backspace to backslash which precedes the
             *  executable filename
             *)
            while env^ <> '\' do begin
                env:= CharPtr(DWord(env)-1);
                end;


            (*
             *  Point to the first letter of the filename
             *)
            env:= CharPtr(DWord(env)+1);

            (*
             *  Print the text up to the dot
             *)
            i:= 0;
            while (i < 12) and (env^ <> '.') do begin
                write(env^);
                env:= CharPtr(DWord(env)+1);
                i:= i + 1;
                end;

            (*
             *  Print out the extension.
             *)
            if i < 12 then begin
                for i:= 0 to 3 do begin
                    write(env^);
                    env:= CharPtr(DWord(env)+1);
                    end;
                end;
            end;

        (*
         *  Put out a Carriage return here
         *)
        writeln;

        (*
         *  See if we've reached the 'Z', the last MCB
         *)
        if mcbPtr^.chain_status = 'Z' then begin 
            Exit;
            end;

        (*
         *  Add paragraph size to pointer segment and
         *  add 1 to cover length of mcb itself
         *)
        mcbPtr:= Ptr(Seg(mcbPtr^)+mcbPtr^.size_paragraphs+1,0);
        end;

end.
