home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* MEMMAP.PAS *)
- (* Das Programm liefert eine ausführliche Speicher- *)
- (* belegungstabelle für alle DOS-Versionen 2.xx und 3.xx. *)
- (* *)
- (* (c) 1989 Norbert Juffa & TOOLBOX *)
- (* ------------------------------------------------------ *)
- PROGRAM MemMap;
-
- USES DOS;
-
- TYPE
- DeviceHdrPtr = ^DeviceHdr;
- DeviceHdr = RECORD
- NextDevice : DeviceHdrPtr;
- Attribute : WORD;
- StratEntry : WORD;
- InterEntry : WORD;
- CASE BOOLEAN OF
- FALSE : (NrOfUnits: BYTE);
- TRUE : (Name: ARRAY[1..8] OF CHAR);
- END;
- DevicePtr = ^Device;
- Device = RECORD
- Address : POINTER;
- Typ : BYTE;
- Name : STRING [15];
- Next : DevicePtr;
- END;
- MCBPtr = ^MCB;
- MCB = RECORD
- Signature : CHAR;
- OwnerProc : WORD;
- BlockLength : WORD;
- Reserved : ARRAY [$5..$F] OF BYTE;
- END;
- DPBPtr = ^DPB;
- DPB = RECORD
- Drive : BYTE;
- DriverUnit : BYTE;
- SectorSize : WORD;
- SectorsPerCluster : BYTE;
- LogSecPerCluster : BYTE;
- FirstFATSector : WORD;
- NrOfFATs : BYTE;
- NrOfDirEntries : WORD;
- FirstDataSector : WORD;
- ClustersPerDrive : WORD;
- SectorsPerFAT : BYTE;
- FirstDirSector : WORD;
- DeviceHeader : DeviceHdrPtr;
- IDByte : BYTE;
- CheckMediaChanged : BYTE;
- NextDPB : DPBPtr;
- Reserved : LONGINT;
- END;
- ProcessPtr = ^Process;
- Process = RECORD
- PSPAddress : WORD;
- Name : STRING [8];
- Next : ProcessPtr;
- END;
- DriverAddr = ARRAY [0..10] OF LONGINT;
-
- VAR
- LogicalDrives,
- DOSVersion : BYTE;
- MSEG, DSEG,
- FSEG, BSEG,
- LSEG, SSEG,
- FCBSEG,
- FCBSize,
- STACKSize,
- IOSYSSize,
- MSDOSSize,
- FILESSize,
- BUFFERSSize,
- LASTDRIVESize : WORD;
- FirstMCB : MCBPtr;
- FirstDPB : DPBPtr;
- Regs : Registers;
- UserDeviceList : DevicePtr;
- ProcessList : ProcessPtr;
-
- FUNCTION Hex(x : WORD) : STRING;
- VAR h : ARRAY [0..15] OF CHAR;
- BEGIN
- h := '0123456789ABCDEF';
- Hex := h[x SHR 12] + h[(x AND $0F00) SHR 8] +
- h[(x AND $00F0) SHR 4] + h[(x AND $000F)];
- END;
-
- FUNCTION PtrToLongint(Ptr : POINTER) : LONGINT;
- BEGIN
- PtrToLongint := LongInt(Seg(Ptr^))*16 + Ofs(Ptr^);
- END;
-
- PROCEDURE AddToDeviceList(ThisDevice : DeviceHdrPtr;
- VAR DeviceList : DevicePtr;
- DriverAddress : DriverAddr;
- NrOfDrives : WORD);
- VAR NewDevice, CurrentDevice : DevicePtr; L : WORD;
- BEGIN
- New(NewDevice);
- IF DeviceList = NIL THEN BEGIN
- DeviceList := NewDevice;
- NewDevice^.Next := NIL;
- END ELSE
- IF PtrToLongint(ThisDevice) <=
- PtrToLongint(DeviceList^.Address) THEN BEGIN
- NewDevice^.Next := DeviceList;
- DeviceList := NewDevice;
- END ELSE BEGIN
- CurrentDevice := DeviceList;
- WHILE (CurrentDevice^.Next <> NIL) AND
- (PtrToLongInt(CurrentDevice) >
- (PtrToLongInt(CurrentDevice^.Next^.Address))) DO
- CurrentDevice := CurrentDevice^.Next;
- NewDevice^.Next := CurrentDevice^.Next;
- CurrentDevice^.Next := NewDevice;
- END;
- NewDevice^.Address := ThisDevice;
- NewDevice^.Typ := (ThisDevice^.Attribute SHR 15) XOR 1;
- IF NewDevice^.Typ = 0 THEN
- NewDevice^.Name := ThisDevice^.Name
- ELSE BEGIN
- NewDevice^.Name := '';
- FOR L := 1 TO NrOfDrives DO
- IF DriverAddress [L] =
- PtrToLongInt(NewDevice^.Address) THEN
- NewDevice^.Name :=
- NewDevice^.Name + Char (L+64) + ':, ';
- Dec(NewDevice^.Name[0], 2);
- END;
- END;
-
- PROCEDURE MakeDeviceList(CurrentDPB : DPBPtr; DSEG: WORD;
- Regs: Registers; DOSVersion: BYTE;
- VAR DeviceList: DevicePtr);
- VAR DriveNr: BYTE; DriverAddress: DriverAddr;
- CurrentDevice: DeviceHdrPtr;
- BEGIN
- DeviceList := NIL;
- DriveNr := 1;
- REPEAT
- DriverAddress[DriveNr] :=
- PtrToLongInt(CurrentDPB^.DeviceHeader);
- CurrentDPB := CurrentDPB^.NextDPB;
- Inc(DriveNr);
- UNTIL(Ofs(CurrentDPB^) = $FFFF);
- IF DOSVersion >= 3 THEN
- CurrentDevice := Ptr(Regs.ES, Regs.BX+34)
- ELSE
- CurrentDevice := Ptr(Regs.ES, Regs.BX+23);
- REPEAT
- IF Seg(CurrentDevice^) > DSEG THEN
- AddToDeviceList(CurrentDevice, DeviceList,
- DriverAddress, DriveNr);
- CurrentDevice := CurrentDevice^.NextDevice;
- UNTIL(Ofs(CurrentDevice^) = $FFFF);
- END;
-
- FUNCTION GetProcessName(PSPSeg : WORD) : STRING;
- TYPE Environment = ARRAY [0..32767] OF CHAR;
- VAR EnvironmentPtr : ^Environment;
- HelpStr : STRING; L : WORD;
- BEGIN
- HelpStr := '';
- EnvironmentPtr := Ptr(MemW[PSPSeg:$2C], 0);
- L := 1;
- WHILE (EnvironmentPtr^[L-1]+EnvironmentPtr^[L]) <> #0#0 DO
- Inc(L);
- Inc(L, 3);
- WHILE EnvironmentPtr^[L] <> #0 DO BEGIN
- HelpStr := HelpStr + EnvironmentPtr^[L];
- Inc(L);
- END;
- REPEAT
- L := Pos('\', HelpStr);
- Delete(HelpStr, 1, L);
- UNTIL L = 0;
- HelpStr := Copy(HelpStr, 1, Pos('.', HelpStr) - 1);
- IF HelpStr = '' THEN HelpStr := '???';
- GetProcessName := HelpStr;
- END;
-
- PROCEDURE AddToProcessList (ProcessID: WORD; Name: STRING;
- VAR ProcessList: ProcessPtr);
- VAR CurrentProcess, NewProcess: ProcessPtr;
- BEGIN
- IF ProcessList = NIL THEN BEGIN
- New(NewProcess);
- NewProcess^.Next := NIL;
- NewProcess^.Name := Name;
- NewProcess^.PSPAddress := ProcessID;
- ProcessList := NewProcess;
- END ELSE BEGIN
- CurrentProcess := ProcessList;
- WHILE (CurrentProcess^.Name <> Name) AND
- (CurrentProcess^.Next <> NIL) DO BEGIN
- CurrentProcess := CurrentProcess^.Next;
- END;
- IF CurrentProcess^.Name <> Name THEN BEGIN
- New (NewProcess);
- NewProcess^.Next := NIL;
- NewProcess^.Name := Name;
- NewProcess^.PSPAddress := ProcessID;
- CurrentProcess^.Next := NewProcess;
- END;
- END;
- END;
-
- PROCEDURE MakeProcessList(CurrentMCB : MCBPtr;
- VAR ProcessList: ProcessPtr);
- VAR ProcessName: STRING [8];
- BEGIN
- REPEAT
- CurrentMCB := Ptr(Seg(CurrentMCB^) +
- CurrentMCB^.BlockLength + 1, 0);
- IF CurrentMCB^.OwnerProc <>
- (Seg(CurrentMCB^) + 1) THEN BEGIN
- ProcessName := GetProcessName(CurrentMCB^.OwnerProc);
- AddToProcessList(CurrentMCB^.OwnerProc,
- ProcessName, ProcessList);
- END;
- UNTIL CurrentMCB^.Signature = 'Z';
- END;
-
- FUNCTION SearchProcessName(ProcessID : WORD;
- ProcessList: ProcessPtr): STRING;
- BEGIN
- WHILE (ProcessList <> NIL) AND
- (ProcessList^.PSPAddress <> ProcessID) DO
- ProcessList:= ProcessList^.Next;
- IF (ProcessList = NIL) OR (DOSVersion < 3) THEN
- SearchProcessName := '???'
- ELSE
- SearchProcessName := ProcessList^.Name;
- END;
-
- PROCEDURE PrintProcessList(CurrentMCB : MCBPtr;
- ProcessList: ProcessPtr);
- VAR ProcName: STRING [8];
- CommandID:WORD;
- Size: LONGINT;
- OldMCB: MCBPtr;
- BEGIN
- CurrentMCB := Ptr(Seg(CurrentMCB^) +
- CurrentMCB^.BlockLength + 1, 0);
- CommandID := Seg (CurrentMCB^)+1;
- WHILE Seg(CurrentMCB^) < PrefixSeg DO BEGIN
- OldMCB := CurrentMCB;
- WHILE (CurrentMCB^.OwnerProc=0) OR
- (CurrentMCB^.OwnerProc = PrefixSeg) DO BEGIN
- CurrentMCB := Ptr(Seg(CurrentMCB^) +
- CurrentMCB^.BlockLength + 1, 0);
- END;
- Size := LongInt(Seg(CurrentMCB^) - Seg(OldMCB^)) * 16;
- IF Size <> 0 THEN
- WriteLn (Hex(Seg(OldMCB^)+1),
- ':0000 Freier Speicherblock ─ ',
- (Size-16):6);
- IF Seg(CurrentMCB^) < PrefixSeg THEN BEGIN
- Write(Hex(Seg(CurrentMCB^)+1), ':0000 ');
- IF (CurrentMCB^.OwnerProc <> (Seg(CurrentMCB^)+1)) AND
- ((Word(Ptr(CurrentMCB^.OwnerProc, $2C)^) =
- Seg(CurrentMCB^)+1)
- OR (Word(Ptr(CurrentMCB^.OwnerProc, $2C)^)=0)) THEN
- Write('Environment ')
- ELSE
- Write('Programm ');
- IF CurrentMCB^.OwnerProc = CommandID THEN
- ProcName := 'COMMAND'
- ELSE
- ProcName := SearchProcessName(CurrentMCB^.OwnerProc,
- ProcessList);
- Write(ProcName, '':12-Length(ProcName));
- WriteLn(LongInt(CurrentMCB^.BlockLength)*16:6);
- CurrentMCB := Ptr(Seg(CurrentMCB^) +
- CurrentMCB^.BlockLength + 1, 0);
- END;
- END;
- END;
-
- PROCEDURE PrintDeviceList (DeviceList: DevicePtr;
- FSEG: WORD);
- CONST DeviceType: ARRAY [0..1] OF STRING [16] =
- ('Character-Device', 'Block-Device');
- BEGIN
- WHILE DeviceList <> NIL DO BEGIN
- Write(Hex(Seg(DeviceList^.Address^)), ':0000 ');
- Write(DeviceType[DeviceList^.Typ]);
- Write('':21-Length(DeviceType[DeviceList^.Typ]));
- Write(DeviceList^.Name, '':12-Length(DeviceList^.Name));
- IF DeviceList^.Next <> NIL THEN
- WriteLn((Seg(DeviceList^.Next^.Address^) -
- Seg(DeviceList^.Address^))*16:6)
- ELSE
- WriteLn((FSEG - Seg(DeviceList^.Address^))*16:6);
- DeviceList := DeviceList^.Next;
- END;
- END;
-
- FUNCTION GetBuffersStart(Regs: Registers; DSEG: WORD): WORD;
- VAR CurrentBuffer: Pointer;
- Start: WORD;
- BEGIN
- IF DOSVersion < 3 THEN
- CurrentBuffer := Pointer(Ptr(Regs.ES, Regs.BX+19)^)
- ELSE
- CurrentBuffer := Pointer(Ptr(Regs.ES, Regs.BX+18)^);
- WHILE Ofs(CurrentBuffer^) <> 0 DO
- CurrentBuffer := Pointer(CurrentBuffer^);
- Start := Seg(CurrentBuffer^);
- REPEAT
- IF (Seg(CurrentBuffer^) < Start) AND
- (Seg(CurrentBuffer^) > DSEG) THEN
- Start := Seg(CurrentBuffer^);
- CurrentBuffer := Pointer(CurrentBuffer^);
- UNTIL Ofs(CurrentBuffer^) = $FFFF;
- GetBuffersStart := Start;
- END;
-
- BEGIN
- Regs.AH := $30; { DOS-Version }
- MSDOS(Regs);
- DOSVersion := Regs.AL;
- Regs.AH := $52; { undokumentierte Funktion : }
- MSDOS(Regs); { wichtige Variablen }
- MSEG := Regs.ES;
- DSEG := Seg(Pointer(Ptr(Regs.ES, Regs.BX-4)^)^);
- FSEG := Seg(Pointer(Pointer(Ptr(Regs.ES, Regs.BX+4)^)^)^);
- BSEG := GetBuffersStart(Regs, DSEG);
- IF DOSVersion >= 3 THEN BEGIN
- LogicalDrives := Byte(Ptr(Regs.ES, Regs.BX+33)^);
- FCBSEG := Seg(Pointer(Ptr(Regs.ES, Regs.BX+26)^)^);
- LSEG := Seg(Pointer(Ptr(Regs.ES, Regs.BX+22)^)^);
- END;
- FirstMCB := Ptr(DSEG, 0);
- FirstDPB := Pointer(Ptr(Regs.ES, Regs.BX)^);
- UserDeviceList := NIL;
- ProcessList := NIL;
- MakeDeviceList(FirstDPB, DSEG, Regs, DOSVersion,
- UserDeviceList);
- IOSYSSize := (MSEG - $70) * 16;
- MSDOSSize := (DSEG - MSEG) * 16;
- IF DOSVersion >= 3 THEN BEGIN
- FILESSize := (FCBSEG - FSEG) * 16;
- FCBSize := (BSEG - FCBSEG) * 16;
- BUFFERSSize := (LSEG - BSEG) * 16;
- LASTDRIVESize:= ((LogicalDrives*81 - 1) DIV 16 + 1)*16;
- SSEG := LSEG + LASTDRIVESize DIV 16;
- STACKSize := (FirstMCB^.BlockLength+1+DSEG-SSEG)*16;
- END ELSE BEGIN
- FILESSize := (BSEG - FSEG) * 16;
- BUFFERSSize := (FirstMCB^.BlockLength+1+DSEG-BSEG)*16;
- END;
- IF FSEG = $FFFF THEN
- FSEG := BSEG;
- MakeProcessList(FirstMCB, ProcessList);
- WriteLn;
- Write('MemMap1.1 Speicherbelegungstabelle');
- WriteLn(' (c) 1988 N.J');
- WriteLn;
- WriteLn(' Adresse Beschreibung ',
- 'Name Größe');
- WriteLn('--------- ------------------ ---',
- '------- ------');
- WriteLn('0000:0000 Interrupt-Vektoren ─ ',
- ' 1024');
- WriteLn('0040:0000 BIOS-Datenbereich ─ ',
- ' 256');
- WriteLn('0050:0000 DOS-Datenbereich ─ ',
- ' 512');
- WriteLn('0070:0000 DOS IO.SYS ',
- IOSYSSize:8);
- WriteLn(Hex(MSEG),':0000 DOS ',
- ' MSDOS.SYS ', MSDOSSize:8);
-
- PrintDeviceList(UserDeviceList, FSEG);
- IF FSEG <> BSEG THEN
- WriteLn(Hex(FSEG),':0000 DOS ',
- ' FILES ', FILESSize:8);
- IF DosVersion >= 3 THEN
- WriteLn(Hex(FCBSEG),':0000 DOS ',
- ' FCBS ', FCBSize:8);
- WriteLn (Hex(BSEG),':0000 DOS ',
- ' BUFFERS ', BUFFERSSize:8);
- IF DOSVersion >= 3 THEN BEGIN
- WriteLn(Hex(LSEG),':0000 DOS ',
- ' LASTDRIVE ', LASTDRIVESize:8);
- IF STACKSize > 0 THEN
- WriteLn(Hex(SSEG),':0000 DOS ',
- ' STACK ', STACKSize:8);
- END;
-
- PrintProcessList (FirstMCB, ProcessList);
-
- END.
- (* ------------------------------------------------------ *)
- (* Ende von MEMMAP.PAS *)