home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / windows / pmldt / pmldt.pas
Pascal/Delphi Source File  |  1993-02-04  |  12KB  |  310 lines

  1. program PMShwLDT;            {Windows Tech Journal #28 1/93 +
  2.                               The Processor and Coprocessor #96/99 -#311}
  3.  
  4. uses Objects, WinAPI, Views, Dialogs, App, Drivers, Strings;
  5.  
  6. type
  7.   PLDTColl = ^TLDTColl;
  8.   TLDTColl = object(TStrCollection)
  9.     constructor Init;
  10.   end;
  11.   PLDTWindow = ^TLDTWindow;
  12.   TLDTWindow = object(TDialog)
  13.     constructor Init;
  14.   end;
  15.   TLDTApp = object(TApplication)
  16.     LDTWindow: PLDTWindow;
  17.     constructor Init;
  18.   end;
  19.  
  20.   AccessedStr = array[0..3] of char;
  21.   CodeDataStr = array[0..3] of char;
  22.   DataWriteStr = array[0..4] of char;
  23.   CodeReadStr = array[0..4] of char;
  24.   ConformingStr = array[0..3] of char;
  25.   UpDownStr = array[0..3] of char;
  26.   PresentStr = array[0..3] of char;
  27.   Bit5Str = array[0..3] of char;
  28.   DefSizeStr = array[0..4] of char;
  29.   GranStr = array[0..3] of char;
  30.  
  31.   TShowDesc = record
  32.    LimitL,
  33.    BaseL: word;
  34.    BaseM,
  35.    AccessRights: byte;
  36.                      {code segment  data/stack segment
  37.                 bit 0   accessed
  38.                 bit 1   readable        writable
  39.                 bit 2   conforming      expand down
  40.                 bit 3   always 1        always 0
  41.                 bit 4   segment type
  42.                 bit 5+6 descriptor privilege level
  43.                 bit 7   present}
  44.    LimitH_Flags,         {80386/486 only, must be 0 on 80286}
  45.                {bit 0/4 LimitH
  46.                 bit 5   available
  47.                 bit 6   default size 16/32 bits
  48.                 bit 7   granularity}
  49.    BaseH: byte;          {80386/486 only, must be 0 on 80286}
  50.   end;
  51.  
  52.   LongRemap = record
  53.     case Word of
  54.       0:(Long: LongInt);
  55.       1:(LoWord, HiWord: Word);
  56.    end;
  57.  
  58. const
  59.   Accessed: array[boolean] of AccessedStr = (' Na',' Ac');
  60.   CodeData: array[boolean] of CodeDataStr = (' Da',' Co');
  61.   DataWrite: array[boolean] of DataWriteStr = (' R  ',' R/W');
  62.   CodeRead: array[boolean] of CodeReadStr = ('  NR','   R');
  63.   Conforming: array[boolean] of ConformingStr = ('  C',' NC');
  64.   UpDown: array[boolean] of UpDownStr = (' Up',' Do');
  65.   Present: array[boolean] of PresentStr = (' Nl',' Lo');
  66.   Bit5: array[boolean] of Bit5Str = (' 5f',' 5t');
  67.   DefSize: array[boolean] of DefSizeStr = (' 16b',' 32b');
  68.                                         {default operands/adress size}
  69.   Gran: array[boolean] of Granstr = (' 1b',' 4k'); {granularity}
  70.  
  71. function HexB(Dest: PChar; B: Byte): PChar;
  72. const
  73.   h: array[0..15] of Char = '0123456789ABCDEF';
  74. begin
  75.   Dest[0] := h[b shr 4];
  76.   Dest[1] := h[b and $0F];
  77.   Dest[2] := #0;
  78.   HexB := Dest;
  79. end;
  80.  
  81. function HexW(Dest: PChar; I: Word): PChar;
  82. begin
  83.   HexB(Dest, Hi(I));
  84.   HexB(@Dest[2], Lo(I));
  85.   HexW := Dest;
  86. end;
  87.  
  88. function HexL(Dest: PChar; l:LongInt): PChar;
  89. var
  90.   lr: LongRemap absolute l;
  91. begin
  92.   HexW(Dest, lr.HiWord);
  93.   HexW(@Dest[4], lr.LoWord);
  94.   HexL := Dest;
  95. end;
  96.  
  97. function GetDescriptor(Selector: Word;
  98.                        var ShowDesc: TShowDesc): Boolean; assembler;
  99. asm
  100.    MOV  BX,Selector
  101.    LES  DI,ShowDesc
  102.    MOV  AX,000BH
  103.    INT  31H
  104.    MOV  AX, 0   {keep carry flag intact}
  105.    JC   @1
  106.    MOV  AX, 1
  107. @1:
  108. end;
  109.  
  110. constructor TLDTColl.Init;
  111. var
  112.   LDTStr, DumStr: array[0..80] of char;
  113.   DumString: String;
  114.   Loop: word;
  115.   ShowDesc: TShowDesc;
  116.   TotalBase,
  117.   TotalLimit: Longint;
  118.   Typ, DPL: word;
  119.   SomeHandle: Thandle;
  120. begin
  121. {  SomeHandle:= GlobalAlloc(GMEM_FIXED, 1024000);}
  122.   inherited Init(500, 100);
  123.   for Loop:=0 to $1fff do  {1FFF is maximum no. of selectors in LDT}
  124.    begin
  125.      if GetDescriptor((Loop shl 3) or 4, ShowDesc) then
  126.         {4=00000100 is LDT only, bits 0 and 1 are automatically
  127.         'blanked out' by CPU when it is accessing the DT}
  128. {     if ShowDesc.AccessRights = 0 then
  129.                            {is it a segment desc. = 1 or gate desc. = 0 ?}
  130.       with ShowDesc do
  131.       begin
  132.         HexW(LDTStr, Loop);
  133.         StrCat(LDTStr, ' ');
  134.         TotalBase:=Longint(BaseL) or (Longint(BaseM) shl 16) or
  135.                                      (Longint(BaseH) shl 24);
  136.         Str(TotalBase:10, DumStr);
  137.         StrCat(LDTStr, DumStr);
  138.         StrCat(LDTStr, '/');
  139.         HexL(DumStr, TotalBase);
  140.         StrCat(LDTStr, DumStr);
  141.         StrCat(LDTStr, ' ');
  142.         TotalLimit:=Longint(LimitL) or (Longint(LimitH_Flags and $0F) shl 16);
  143.         HexL(DumStr, TotalLimit);
  144.         StrCat(LDTStr, @DumStr[3]);     {only 20 bits can be significant}
  145.         StrCat(LDTStr, Accessed[AccessRights and $01 > 0]);
  146.         if AccessRights and $08 > 0 then      {code or data?}
  147.         begin
  148.            StrCat(LDTStr, CodeData[True]);
  149.            StrCat(LDTStr, CodeRead[AccessRights and $02 > 0]);
  150.            StrCat(LDTStr, Conforming[AccessRights and $04 > 0]);
  151.          end
  152.          else begin
  153.                 StrCat(LDTStr, CodeData[False]);
  154.                 StrCat(LDTStr, DataWrite[AccessRights and $02 > 0]);
  155.                 StrCat(LDTStr, UpDown[Typ and $04 > 0]);
  156.               end;
  157.         StrCat(LDTStr, ' ');
  158.         DPL:=(AccessRights shr 5) and $03;
  159.         HexW(DumStr, DPL);
  160.         StrCat(LDTStr, DumStr);
  161.         StrCat(LDTStr, Present[AccessRights and $80 > 0]);
  162.         StrCat(LDTStr, Bit5[LimitH_Flags and $20 > 0]);
  163.         StrCat(LDTStr, DefSize[LimitH_Flags and $40 > 0]);
  164.         StrCat(LDTStr, Gran[LimitH_Flags and $80 > 0]);
  165.         DumString:=StrPas(LDTStr);
  166.         Insert(NewStr(DumString));
  167.       end;
  168.    end;
  169.   StrCopy(LDTStr, 'Number of selectors displayed: ');
  170.   Str(Count, DumStr);
  171.   StrCat(LDTStr, DumStr);
  172.   DumString:=StrPas(LDTStr);
  173.   Insert(NewStr(DumString));
  174. end;
  175.  
  176. constructor TLDTWindow.Init;
  177. var
  178.   R: TRect;
  179.   Control: PView;
  180.   ScrollBar: PScrollBar;
  181. begin
  182.   R.Assign(0, 0, 80, 23);
  183.   inherited Init(R, 'Protected Mode (Borland) LDT List Window');
  184.   R.Assign(78, 1, 79, 22);
  185.   New(ScrollBar, Init(R));
  186.   Insert(ScrollBar);
  187.   R.Assign(1, 1, 78, 22);
  188.   Control := New(PListBox, Init(R, 1, ScrollBar));
  189.   Insert(Control);
  190.   PListBox(Control)^.NewList(New(PLDTColl, Init));
  191. end;
  192.  
  193. constructor TLDTApp.Init;
  194. begin
  195.   inherited Init;
  196.   LDTWindow := New(PLDTWindow, Init);
  197.   InsertWindow(LDTWindow);
  198. end;
  199.  
  200. var
  201.   LDTApp: TLDTApp;
  202. begin
  203.   LDTApp.Init;
  204.   LDTApp.Run;
  205.   LDTApp.Done;
  206. end.
  207.  
  208. A few typical screens on my system looks like:
  209.  
  210. ╔═[■]══════════════ Protected Mode (Borland) LDT List Window ═
  211. ║ 00BA (= number of selectors displayed)
  212. ║ 0011     188784/0002E170 0FFFF Ac Co   R  C 0003 Nl 16b 1b
  213. ║ 0012     191616/0002EC80 00A8F Ac Da R/W Up 0003 Nl 16b 1b
  214. ║ 0013     194304/0002F700 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  215. ║ 0014     188528/0002E070 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  216. ║ 0015     188336/0002DFB0 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  217. ║ 0016    2185296/00215850 0255F Ac Co   R  C 0003 Nl 16b 1b
  218. ║ 0017     646704/0009DE30 021CF Ac Da R/W Up 0003 Nl 16b 1b
  219. ║ 0018    2185296/00215850 0255F Ac Da R/W Up 0003 Nl 16b 1b
  220. ║ 0019    2185296/00215850 0255F Na Da R/W Up 0003 Nl 16b 1b
  221. ║ 001A    2209200/0021B5B0 00FFF Ac Da R/W Up 0003 Nl 16b 1b
  222. ║ 001B     188784/0002E170 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  223. ║ 001C    2213296/0021C5B0 0C2AF Ac Co   R  C 0003 Nl 16b 1b
  224. ║ 001D    2263120/00228850 06DBF Ac Da R/W Up 0003 Nl 16b 1b
  225. ║ 001E    2213296/0021C5B0 0C2AF Ac Da R/W Up 0003 Nl 16b 1b
  226. ║ 001F     245168/0003BDB0 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  227. ║ 0020          0/00000000 00000 Na Da R/W Up 0003 Nl 16b 1b
  228. ║ 0021    2213296/0021C5B0 0C2AF Ac Da R/W Up 0003 Nl 16b 1b
  229. ║ 0022    2286000/0022E1B0 0032F Ac Da R/W Up 0003 Nl 16b 1b
  230. ║ 0023    2286816/0022E4E0 0056E Ac Da R/W Up 0003 Nl 16b 1b
  231. ║ 0024    2288208/0022EA50 00A00 Ac Da R/W Up 0003 Nl 16b 1b
  232.  
  233. ║ 0025    2290768/0022F450 001AE Ac Da R/W Up 0003 Nl 16b 1b
  234. ║ 0026          0/00000000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  235. ║ 0027          0/00000000 FFFFF Na Da R/W Up 0003 Nl 16b 4k
  236. ║ 0028       1024/00000400 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  237. ║ 0029     655360/000A0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  238. ║ 002A     720896/000B0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  239. ║ 002B     753664/000B8000 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  240. ║ 002C     786432/000C0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  241. ║ 002D     851968/000D0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  242. ║ 002E     917504/000E0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  243. ║ 002F     983040/000F0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  244. ║ 0030       4448/00001160 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  245. ║ 0031    3693024/003859E0 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  246. ║ 0032    2213296/0021C5B0 0C2AF Ac Da R/W Up 0003 Nl 16b 1b
  247. ║ 0033    3700288/00387640 01C5F Ac Da R/W Up 0003 Nl 16b 1b
  248. ║ 0034    4119280/003EDAF0 01FFF Ac Da R/W Up 0003 Nl 16b 1b
  249. ║ 0035     167936/00029000 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  250. ║ 0036     167744/00028F40 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
  251. ║ 0037          0/00000000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
  252. ║ 0038    4127472/003EFAF0 00301 Ac Da R/W Up 0003 Nl 16b 1b
  253. ║ 0039 1414792540/5454055C 0055C Na Da R/W Up 0003 Nl 16b 1b
  254.  
  255. The selector with sequential number 2B is the one for the PMode
  256. variable SegB800.
  257.  
  258. Selector number 39 is a mystery to me.
  259. Its BaseH is NOT zero as it should be.
  260. On my system there are four (39, 69, 8B and BB) of those selectors.
  261. In case anybody has an explanation for this I would like to know.
  262.  
  263. The last three columns in the display are not really relevant as they
  264. are based on a zero value of that part of the descriptor.
  265. This can't be different as the program operates in the 286 segmented
  266. memory model.
  267.  
  268. The memory allocation on line 121 can be varied to see different effects.
  269.  
  270. Cees Binkhorst/Febr. 2, 1993
  271. CIS 100016, 3552
  272.  
  273. Selector number 39 is no longer a mystery as it is a selector pointing
  274. to a segment that is NOT LOADED.
  275. This should be indicated by bit 7 of the AccessRights.
  276. In the original version of PMShwLDT this bit was tested against $8000,
  277. which obviously is a byte too far, and should be tested against $80.
  278. It will now correctly show if a segment is present or not.
  279.  
  280. If a segment is not present, only the field AccessRights is showing
  281. values that are predetermined by the manufacturer of the CPU.
  282. The other parts of the descriptor are used by the system implementors
  283. (Borland in this case) as they see fit and have, as far as I know,
  284. not yet been documented.
  285. It is normally used in 'virtual memory' situations to swap memory to disk
  286. and bring it back through a processor exception in case the descriptor is
  287. accessed. Room for experiments to find the meaning of the figures!
  288.  
  289. To be complete I have also included bit 5 in the field LimitH_Flags in the
  290. display . This bit is 'available to programmers' but because of the
  291. 286-segmented nature of the DPMI implementation not relevant as it must
  292. be zero.
  293.  
  294. The new display now looks like:
  295. ╔═[■]══════════════ Protected Mode (Borland) LDT List Window ════
  296. ║ 00AE (= number of selectors displayed)
  297. ║ 0011     188784/0002E170 0FFFF Ac Co   R  C 0003 Lo 5f 16b 1b
  298. ║ 0012     191616/0002EC80 00A8F Ac Da R/W Up 0003 Lo 5f 16b 1b
  299. ║ 0013     194304/0002F700 0FFFF Ac Da R/W Up 0003 Lo 5f 16b 1b
  300. ║ 0014     188528/0002E070 0FFFF Ac Da R/W Up 0003 Lo 5f 16b 1b
  301. ║ 0015     188336/0002DFB0 0FFFF Ac Da R/W Up 0003 Lo 5f 16b 1b
  302. ║ 0016    2185296/00215850 0255F Ac Co   R  C 0003 Lo 5f 16b 1b
  303. ║ 0017     646704/0009DE30 021CF Ac Da R/W Up 0003 Lo 5f 16b 1b
  304. ...
  305. ║ 0037          0/00000000 0FFFF Na Da R/W Up 0003 Lo 5f 16b 1b
  306. ║ 0038    4127472/003EFAF0 00301 Ac Da R/W Up 0003 Lo 5f 16b 1b
  307. ║ 0039 1414792540/5454055C 0055C Na Da R/W Up 0003 Nl 5f 16b 1b
  308. ...                                    present bit ^
  309.  
  310. Cees/Febr. 3, 1993