home *** CD-ROM | disk | FTP | other *** search
/ Delphi Programming Unleashed / Delphi_Programming_Unleashed_SAMS_Publishing_1995.iso / chap17 / pmldt / pmldt.pas
Encoding:
Pascal/Delphi Source File  |  1995-03-21  |  11.3 KB  |  318 lines

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