program GetMem;
{ Looks to page 0 (the PSP, field 2) of current running program, grabbing
  "size of memory" integer (16-byte paragraph count).

  As explained on pages 262-263, Norton's Programmer's Guide for the IBM PC,
  this is the same figure CHKDSK reports.  However amount of memory reported
  may NOT be the actual physical size of memory.  It will show how much
  memory can be used.

  Field 4 gives further information about memory if we have to work with
  less than 64Kb available.  I haven't bothered with that at this point.
  David Kirschbaum, Toad Hall
}

TYPE
  regpack = Record
              ax,bx,cx,dx,bp,di,si,ds,es,flags: INTEGER;
            END;

CONST
  regs : regpack = (ax:0;bx:0;cx:0;dx:0;bp:0;di:0;si:0;ds:0;
                    es:0;flags:0);

VAR
  rec     : regpack Absolute regs;
  k,
  ourDSeg,
  ourCSeg : INTEGER;
  r,
  maxmem,
  k64     : REAL;

PROCEDURE GetSize;
  {uses DOS interrupt 18 AND low-memory location 413H}
  BEGIN
    Intr($12,rec);             { get usable memory in Kb}
    k := rec.ax;               { here's the Kb}
    maxmem := k * 1024.0;      { bytify it}
    Write('Interrupt 18 system Kb: ',k:3);
    k := Memw[0000:$0413];    { also kept in low memory}
    Write(', and low memory value: ',k:3);
    Writeln(' (',maxmem:6:0,' bytes)');
    Writeln('They oughtta be the same!');
  END;

PROCEDURE GetMem;

    FUNCTION CMem(Seg : INTEGER) : REAL;
      BEGIN
        k := MemW[Seg:$0002];
        if k >= 0 THEN r := k * 1.0    {compensate for stupid maxint}
        ELSE r := k64 + (k * 1.0);
        write(': paragraphs used: ',r:5:0);
        r := r * 16.0;
        Write(' (bytes: ',r:7:0);
        CMem := maxmem - r;
        Write('), remaining: ');
      END;

  BEGIN
    {show you what likely segment registers return}
    Writeln('ourCSeg: ',ourCSeg:6, CMem(ourCSeg):7:0);
    Writeln('ourDSeg: ',ourDSeg:6, CMem(ourDSeg):7:0);
    Writeln('   CSEG: ',   CSeg:6, CMem(CSEG):7:0);
    Writeln('   DSEG: ',   DSeg:6, CMem(DSEG):7:0);
  END;

BEGIN
  k64 := 1024.0 * 64.0;
  GetSize;
  ourDSeg := rec.ds;
  ourCSeg := rec.es;
  GetMem;
END.
