fpregs.pas 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998-2000 by Pierre Muller
  5. Register debug routines for the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPRegs;
  13. interface
  14. uses
  15. {$ifdef win32}
  16. Windows,
  17. {$endif win32}
  18. Objects,Dialogs,Drivers,Views,
  19. FPViews;
  20. const
  21. MaxRegs = 128;
  22. type
  23. {$ifdef TP}
  24. dword = longint;
  25. {$endif TP}
  26. {$undef cpu_known}
  27. TIntRegs = record
  28. {$ifndef test_generic_cpu}
  29. {$ifdef I386}
  30. {$define cpu_known}
  31. eax,ebx,ecx,edx,eip,esi,edi,esp,ebp : dword;
  32. cs,ds,es,ss,fs,gs : word;
  33. eflags : dword;
  34. {$endif I386}
  35. {$ifdef m68k}
  36. {$define cpu_known}
  37. d0,d1,d2,d3,d4,d5,d6,d7 : dword;
  38. a0,a1,a2,a3,a4,a5,fp,sp : dword;
  39. ps,pc : dword;
  40. {$endif m68k}
  41. {$ifdef powerpc}
  42. {$define cpu_known}
  43. r : array [0..31] of dword;
  44. pc,ps,cr,lr,ctr,xer : dword;
  45. {$endif powerpc}
  46. {$endif not test_generic_cpu}
  47. {$ifndef cpu_known}
  48. reg : array [0..MaxRegs-1] of string;
  49. {$endif not cpu_known}
  50. end;
  51. PRegistersView = ^TRegistersView;
  52. TRegistersView = object(TView)
  53. NewReg,OldReg : TIntRegs;
  54. InDraw : boolean;
  55. GDBCount : longint;
  56. constructor Init(var Bounds: TRect);
  57. procedure Draw;virtual;
  58. destructor Done; virtual;
  59. end;
  60. PRegistersWindow = ^TRegistersWindow;
  61. TRegistersWindow = Object(TFPDlgWindow)
  62. RV : PRegistersView;
  63. Constructor Init;
  64. constructor Load(var S: TStream);
  65. procedure Store(var S: TStream);
  66. procedure Update; virtual;
  67. destructor Done; virtual;
  68. end;
  69. TFPURegs = record
  70. {$ifndef test_generic_cpu}
  71. {$ifdef I386}
  72. st0,st1,st2,st3,st4,st5,st6,st7 :string;
  73. ftag,fop,fctrl,fstat,fiseg,foseg : word;
  74. fioff,fooff : cardinal;
  75. {$endif I386}
  76. {$ifdef m68k}
  77. fp0,fp1,fp2,fp3,fp4,fp5,fp6,fp7 : string;
  78. fpcontrol,fpstatus,fpiaddr : dword;
  79. {$endif m68k}
  80. {$ifdef powerpc}
  81. f : array [0..31] of string;
  82. {$endif powerpc}
  83. {$endif not test_generic_cpu}
  84. {$ifndef cpu_known}
  85. freg : array [0..MaxRegs-1] of string;
  86. {$endif not cpu_known}
  87. end;
  88. PFPUView = ^TFPUView;
  89. TFPUView = object(TView)
  90. NewReg,OldReg : TFPURegs;
  91. InDraw : boolean;
  92. GDBCount : longint;
  93. {$ifndef cpu_known}
  94. UseInfoFloat : boolean;
  95. {$endif not cpu_known}
  96. constructor Init(var Bounds: TRect);
  97. procedure Draw;virtual;
  98. destructor Done; virtual;
  99. end;
  100. PFPUWindow = ^TFPUWindow;
  101. TFPUWindow = Object(TFPDlgWindow)
  102. RV : PFPUView;
  103. Constructor Init;
  104. constructor Load(var S: TStream);
  105. procedure Store(var S: TStream);
  106. procedure Update; virtual;
  107. destructor Done; virtual;
  108. end;
  109. procedure InitRegistersWindow;
  110. procedure DoneRegistersWindow;
  111. procedure InitFPUWindow;
  112. procedure DoneFPUWindow;
  113. procedure RegisterFPRegsViews;
  114. implementation
  115. uses
  116. Strings,
  117. {$ifndef NODEBUG}
  118. GDBCon,GDBInt,
  119. {$endif NODEBUG}
  120. App,Menus,
  121. WViews,WEditor,
  122. {$ifdef powerpc}
  123. wutils, { for inttostr }
  124. {$endif powerpc}
  125. FPConst,FPVars,
  126. FPString,
  127. FPDebug;
  128. Const
  129. RRegistersWindow: TStreamRec = (
  130. ObjType: 1711;
  131. VmtLink: Ofs(TypeOf(TRegistersWindow)^);
  132. Load: @TRegistersWindow.Load;
  133. Store: @TRegistersWindow.Store
  134. );
  135. RRegistersView: TStreamRec = (
  136. ObjType: 1712;
  137. VmtLink: Ofs(TypeOf(TRegistersView)^);
  138. Load: @TRegistersView.Load;
  139. Store: @TRegistersView.Store
  140. );
  141. RFPUWindow: TStreamRec = (
  142. ObjType: 1713;
  143. VmtLink: Ofs(TypeOf(TFPUWindow)^);
  144. Load: @TFPUWindow.Load;
  145. Store: @TFPUWindow.Store
  146. );
  147. RFPUView: TStreamRec = (
  148. ObjType: 1714;
  149. VmtLink: Ofs(TypeOf(TFPUView)^);
  150. Load: @TFPUView.Load;
  151. Store: @TFPUView.Store
  152. );
  153. {****************************************************************************
  154. TRegistersView
  155. ****************************************************************************}
  156. function GetIntRegs(var rs : TIntRegs) : boolean;
  157. var
  158. p,po : pchar;
  159. p1 : pchar;
  160. reg,value : string;
  161. buffer : array[0..255] of char;
  162. v : dword;
  163. code : word;
  164. i : byte;
  165. begin
  166. GetIntRegs:=false;
  167. {$ifndef NODEBUG}
  168. Debugger^.Command('info registers');
  169. if Debugger^.Error then
  170. exit
  171. else
  172. begin
  173. {$ifndef cpu_known}
  174. i:=0;
  175. {$endif not cpu_known}
  176. po:=StrNew(Debugger^.GetOutput);
  177. p:=po;
  178. if assigned(p) then
  179. begin
  180. fillchar(rs,sizeof(rs),0);
  181. p1:=strscan(p,' ');
  182. while assigned(p1) do
  183. begin
  184. {$ifndef cpu_known}
  185. p1:=strscan(p,#10);
  186. if assigned(p1) then
  187. begin
  188. strlcopy(buffer,p,p1-p);
  189. rs.reg[i]:=ExtractTabs(strpas(buffer),8);
  190. if i<MaxRegs-1 then
  191. inc(i);
  192. end;
  193. {$else cpu_known}
  194. strlcopy(buffer,p,p1-p);
  195. reg:=strpas(buffer);
  196. p:=strscan(p,'$');
  197. p1:=strscan(p,#9);
  198. strlcopy(buffer,p,p1-p);
  199. value:=strpas(buffer);
  200. val(value,v,code);
  201. {$ifdef i386}
  202. if reg='eax' then
  203. rs.eax:=v
  204. else if reg='ebx' then
  205. rs.ebx:=v
  206. else if reg='ecx' then
  207. rs.ecx:=v
  208. else if reg='edx' then
  209. rs.edx:=v
  210. else if reg='eip' then
  211. rs.eip:=v
  212. else if reg='esi' then
  213. rs.esi:=v
  214. else if reg='edi' then
  215. rs.edi:=v
  216. else if reg='esp' then
  217. rs.esp:=v
  218. else if reg='ebp' then
  219. rs.ebp:=v
  220. { under win32 flags are on a register named ps !! PM }
  221. else if (reg='eflags') or (reg='ps') then
  222. rs.eflags:=v
  223. else if reg='cs' then
  224. rs.cs:=v
  225. else if reg='ds' then
  226. rs.ds:=v
  227. else if reg='es' then
  228. rs.es:=v
  229. else if reg='fs' then
  230. rs.fs:=v
  231. else if reg='gs' then
  232. rs.gs:=v
  233. else if reg='ss' then
  234. rs.ss:=v;
  235. {$endif i386}
  236. {$ifdef m68k}
  237. if reg='d0' then
  238. rs.d0:=v
  239. else if reg='d1' then
  240. rs.d1:=v
  241. else if reg='d2' then
  242. rs.d2:=v
  243. else if reg='d3' then
  244. rs.d3:=v
  245. else if reg='d4' then
  246. rs.d4:=v
  247. else if reg='d5' then
  248. rs.d5:=v
  249. else if reg='d6' then
  250. rs.d6:=v
  251. else if reg='d7' then
  252. rs.d7:=v
  253. else if reg='a0' then
  254. rs.a0:=v
  255. else if reg='a1' then
  256. rs.a1:=v
  257. else if reg='a2' then
  258. rs.a2:=v
  259. else if reg='a3' then
  260. rs.a3:=v
  261. else if reg='a4' then
  262. rs.a4:=v
  263. else if reg='a5' then
  264. rs.a5:=v
  265. else if reg='fp' then
  266. rs.fp:=v
  267. else if reg='sp' then
  268. rs.sp:=v
  269. else if (reg='ps') then
  270. rs.ps:=v
  271. else if reg='pc' then
  272. rs.pc:=v;
  273. {$endif m68k}
  274. {$ifdef powerpc}
  275. if (reg[1]='r') then
  276. begin
  277. for i:=0 to 31 do
  278. if reg='r'+inttostr(i) then
  279. rs.r[i]:=v;
  280. end
  281. { other regs
  282. pc,ps,cr,lr,ctr,xer : dword; }
  283. else if (reg='pc') then
  284. rs.pc:=v
  285. else if (reg='ps') then
  286. rs.ps:=v
  287. else if (reg='lr') then
  288. rs.lr:=v
  289. else if (reg='ctr') then
  290. rs.ctr:=v
  291. else if (reg='xer') then
  292. rs.xer:=v;
  293. {$endif powerpc}
  294. {$endif not cpu_known}
  295. p:=strscan(p1,#10);
  296. if assigned(p) then
  297. begin
  298. p1:=strscan(p,' ');
  299. inc(p);
  300. end
  301. else
  302. break;
  303. end;
  304. { free allocated memory }
  305. strdispose(po);
  306. end
  307. else
  308. exit;
  309. end;
  310. { do not open a messagebox for such errors }
  311. Debugger^.got_error:=false;
  312. GetIntRegs:=true;
  313. {$endif}
  314. end;
  315. constructor TRegistersView.Init(var Bounds: TRect);
  316. begin
  317. inherited init(Bounds);
  318. InDraw:=false;
  319. FillChar(OldReg,Sizeof(OldReg),#0);
  320. FillChar(NewReg,Sizeof(NewReg),#0);
  321. GrowMode:=gfGrowHiX or GfGrowHiY;
  322. GDBCount:=-1;
  323. end;
  324. procedure TRegistersView.Draw;
  325. var
  326. rs : tintregs;
  327. OK : boolean;
  328. color :byte;
  329. i : byte;
  330. procedure SetColor(x,y : longint);
  331. begin
  332. if x=y then
  333. color:=7
  334. else
  335. color:=8;
  336. end;
  337. procedure SetStrColor(const x,y : string);
  338. begin
  339. if x=y then
  340. color:=7
  341. else
  342. color:=8;
  343. end;
  344. begin
  345. inherited draw;
  346. {$ifdef NODEBUG}
  347. WriteStr(1,0,'<no values available>',7);
  348. {$else NODEBUG}
  349. If not assigned(Debugger) then
  350. begin
  351. WriteStr(1,0,'<no values available>',7);
  352. exit;
  353. end;
  354. if InDraw then exit;
  355. InDraw:=true;
  356. if GDBCount<>Debugger^.RunCount then
  357. begin
  358. OldReg:=NewReg;
  359. OK:=GetIntRegs(rs);
  360. NewReg:=rs;
  361. GDBCount:=Debugger^.RunCount;
  362. end
  363. else
  364. begin
  365. rs:=NewReg;
  366. OK:=true;
  367. end;
  368. if OK then
  369. begin
  370. {$ifdef cpu_known}
  371. {$ifdef i386}
  372. SetColor(rs.eax,OldReg.eax);
  373. WriteStr(1,0,'EAX '+HexStr(longint(rs.eax),8),color);
  374. SetColor(rs.ebx,OldReg.ebx);
  375. WriteStr(1,1,'EBX '+HexStr(longint(rs.ebx),8),color);
  376. SetColor(rs.ecx,OldReg.ecx);
  377. WriteStr(1,2,'ECX '+HexStr(longint(rs.ecx),8),color);
  378. SetColor(rs.edx,OldReg.edx);
  379. WriteStr(1,3,'EDX '+HexStr(longint(rs.edx),8),color);
  380. SetColor(rs.eip,OldReg.eip);
  381. WriteStr(1,4,'EIP '+HexStr(longint(rs.eip),8),color);
  382. SetColor(rs.esi,OldReg.esi);
  383. WriteStr(1,5,'ESI '+HexStr(longint(rs.esi),8),color);
  384. SetColor(rs.edi,OldReg.edi);
  385. WriteStr(1,6,'EDI '+HexStr(longint(rs.edi),8),color);
  386. SetColor(rs.esp,OldReg.esp);
  387. WriteStr(1,7,'ESP '+HexStr(longint(rs.esp),8),color);
  388. SetColor(rs.ebp,OldReg.ebp);
  389. WriteStr(1,8,'EBP '+HexStr(longint(rs.ebp),8),color);
  390. SetColor(rs.cs,OldReg.cs);
  391. WriteStr(14,0,'CS '+HexStr(rs.cs,4),color);
  392. SetColor(rs.ds,OldReg.ds);
  393. WriteStr(14,1,'DS '+HexStr(rs.ds,4),color);
  394. SetColor(rs.es,OldReg.es);
  395. WriteStr(14,2,'ES '+HexStr(rs.es,4),color);
  396. SetColor(rs.fs,OldReg.fs);
  397. WriteStr(14,3,'FS '+HexStr(rs.fs,4),color);
  398. SetColor(rs.gs,OldReg.gs);
  399. WriteStr(14,4,'GS '+HexStr(rs.gs,4),color);
  400. SetColor(rs.ss,OldReg.ss);
  401. WriteStr(14,5,'SS '+HexStr(rs.ss,4),color);
  402. SetColor(rs.eflags and $1,OldReg.eflags and $1);
  403. WriteStr(22,0,'c='+chr(byte((rs.eflags and $1)<>0)+48),color);
  404. SetColor(rs.eflags and $20,OldReg.eflags and $20);
  405. WriteStr(22,1,'z='+chr(byte((rs.eflags and $20)<>0)+48),color);
  406. SetColor(rs.eflags and $80,OldReg.eflags and $80);
  407. WriteStr(22,2,'s='+chr(byte((rs.eflags and $80)<>0)+48),color);
  408. SetColor(rs.eflags and $800,OldReg.eflags and $800);
  409. WriteStr(22,3,'o='+chr(byte((rs.eflags and $800)<>0)+48),color);
  410. SetColor(rs.eflags and $4,OldReg.eflags and $4);
  411. WriteStr(22,4,'p='+chr(byte((rs.eflags and $4)<>0)+48),color);
  412. SetColor(rs.eflags and $200,OldReg.eflags and $200);
  413. WriteStr(22,5,'i='+chr(byte((rs.eflags and $200)<>0)+48),color);
  414. SetColor(rs.eflags and $10,OldReg.eflags and $10);
  415. WriteStr(22,6,'a='+chr(byte((rs.eflags and $10)<>0)+48),color);
  416. SetColor(rs.eflags and $400,OldReg.eflags and $400);
  417. WriteStr(22,7,'d='+chr(byte((rs.eflags and $400)<>0)+48),color);
  418. {$endif i386}
  419. {$ifdef m68k}
  420. SetColor(rs.d0,OldReg.d0);
  421. WriteStr(1,0,'d0 '+HexStr(longint(rs.d0),8),color);
  422. SetColor(rs.d1,OldReg.d1);
  423. WriteStr(1,1,'d1 '+HexStr(longint(rs.d1),8),color);
  424. SetColor(rs.d2,OldReg.d2);
  425. WriteStr(1,2,'d2 '+HexStr(longint(rs.d2),8),color);
  426. SetColor(rs.d3,OldReg.d3);
  427. WriteStr(1,3,'d3 '+HexStr(longint(rs.d3),8),color);
  428. SetColor(rs.d4,OldReg.d4);
  429. WriteStr(1,4,'d4 '+HexStr(longint(rs.d4),8),color);
  430. SetColor(rs.d5,OldReg.d5);
  431. WriteStr(1,5,'d5 '+HexStr(longint(rs.d5),8),color);
  432. SetColor(rs.d6,OldReg.d6);
  433. WriteStr(1,6,'d6 '+HexStr(longint(rs.d6),8),color);
  434. SetColor(rs.d7,OldReg.d7);
  435. WriteStr(1,7,'d7 '+HexStr(longint(rs.d7),8),color);
  436. SetColor(rs.a0,OldReg.a0);
  437. WriteStr(14,0,'a0 '+HexStr(longint(rs.a0),8),color);
  438. SetColor(rs.a1,OldReg.a1);
  439. WriteStr(14,1,'a1 '+HexStr(longint(rs.a1),8),color);
  440. SetColor(rs.a2,OldReg.a2);
  441. WriteStr(14,2,'a2 '+HexStr(longint(rs.a2),8),color);
  442. SetColor(rs.a3,OldReg.a3);
  443. WriteStr(14,3,'a3 '+HexStr(longint(rs.a3),8),color);
  444. SetColor(rs.a4,OldReg.a4);
  445. WriteStr(14,4,'a4 '+HexStr(longint(rs.a4),8),color);
  446. SetColor(rs.a5,OldReg.a5);
  447. WriteStr(14,5,'a5 '+HexStr(longint(rs.a5),8),color);
  448. SetColor(rs.fp,OldReg.fp);
  449. WriteStr(14,6,'fp '+HexStr(longint(rs.fp),8),color);
  450. SetColor(rs.sp,OldReg.sp);
  451. WriteStr(14,7,'sp '+HexStr(longint(rs.sp),8),color);
  452. SetColor(rs.pc,OldReg.pc);
  453. WriteStr(1,8,'pc '+HexStr(longint(rs.pc),8),color);
  454. SetColor(rs.ps and $1,OldReg.ps and $1);
  455. WriteStr(22,8,' c'+chr(byte((rs.ps and $1)<>0)+48),color);
  456. SetColor(rs.ps and $2,OldReg.ps and $2);
  457. WriteStr(19,8,' v'+chr(byte((rs.ps and $2)<>0)+48),color);
  458. SetColor(rs.ps and $4,OldReg.ps and $4);
  459. WriteStr(16,8,' z'+chr(byte((rs.ps and $4)<>0)+48),color);
  460. SetColor(rs.ps and $8,OldReg.ps and $8);
  461. WriteStr(14,8, 'x'+chr(byte((rs.ps and $8)<>0)+48),color);
  462. {$endif m68k}
  463. {$ifdef powerpc}
  464. for i:=0 to 15 do
  465. begin
  466. SetColor(rs.r[i],OldReg.r[i]);
  467. if i<10 then
  468. WriteStr(1,i,'r'+IntToStr(i)+' '+HexStr(longint(rs.r[i]),8),color)
  469. else
  470. WriteStr(1,i,'r'+IntToStr(i)+' '+HexStr(longint(rs.r[i]),8),color);
  471. end;
  472. for i:=16 to 31 do
  473. begin
  474. SetColor(rs.r[i],OldReg.r[i]);
  475. WriteStr(15,i-16,'r'+IntToStr(i)+' '+HexStr(longint(rs.r[i]),8),color);
  476. end;
  477. { other regs pc,ps,cr,lr,ctr,xer : dword; }
  478. SetColor(rs.pc,OldReg.pc);
  479. WriteStr(1,16,'pc '+HexStr(longint(rs.pc),8),color);
  480. SetColor(rs.ps,OldReg.ps);
  481. WriteStr(15,16,'ps '+HexStr(longint(rs.ps),8),color);
  482. SetColor(rs.lr,OldReg.lr);
  483. WriteStr(1,17,'lr '+HexStr(longint(rs.lr),8),color);
  484. SetColor(rs.ctr,OldReg.ctr);
  485. WriteStr(15,17,'ctr '+HexStr(longint(rs.ctr),8),color);
  486. SetColor(rs.xer,OldReg.xer);
  487. WriteStr(15,18,'xer '+HexStr(longint(rs.xer),8),color);
  488. {$endif powerpc}
  489. {$else cpu_known}
  490. for i:=0 to MaxRegs-1 do
  491. begin
  492. SetStrColor(rs.reg[i],OldReg.reg[i]);
  493. WriteStr(1,i,rs.reg[i],color);
  494. end;
  495. {$endif cpu_known}
  496. end
  497. else
  498. WriteStr(0,0,'<debugger error>',7);
  499. InDraw:=false;
  500. {$endif NODEBUG}
  501. end;
  502. destructor TRegistersView.Done;
  503. begin
  504. inherited done;
  505. end;
  506. {****************************************************************************
  507. TRegistersWindow
  508. ****************************************************************************}
  509. constructor TRegistersWindow.Init;
  510. var
  511. R : TRect;
  512. begin
  513. Desktop^.GetExtent(R);
  514. {$ifdef i386}
  515. R.A.X:=R.B.X-28;
  516. R.B.Y:=R.A.Y+11;
  517. {$endif i386}
  518. {$ifdef m68k}
  519. R.A.X:=R.B.X-28;
  520. R.B.Y:=R.A.Y+11;
  521. {$endif m68k}
  522. {$ifdef powerpc}
  523. R.A.X:=R.B.X-28;
  524. R.B.Y:=R.A.Y+22;
  525. {$endif powerpc}
  526. {$ifndef cpu_known}
  527. R.A.X:=R.B.X-28;
  528. R.B.Y:=R.A.Y+22;
  529. {$endif cpu_known}
  530. inherited Init(R,dialog_registers, wnNoNumber);
  531. Flags:=wfClose or wfMove;
  532. {$ifndef cpu_known}
  533. Flags:=Flags or wfgrow;
  534. {$endif cpu_known}
  535. Palette:=wpCyanWindow;
  536. HelpCtx:=hcRegistersWindow;
  537. R.Assign(1,1,Size.X-2,Size.Y-2);
  538. RV:=new(PRegistersView,init(R));
  539. Insert(RV);
  540. If assigned(RegistersWindow) then
  541. dispose(RegistersWindow,done);
  542. RegistersWindow:=@Self;
  543. Update;
  544. end;
  545. constructor TRegistersWindow.Load(var S: TStream);
  546. begin
  547. inherited load(S);
  548. GetSubViewPtr(S,RV);
  549. If assigned(RegistersWindow) then
  550. dispose(RegistersWindow,done);
  551. RegistersWindow:=@Self;
  552. end;
  553. procedure TRegistersWindow.Store(var S: TStream);
  554. begin
  555. inherited Store(s);
  556. PutSubViewPtr(S,RV);
  557. end;
  558. procedure TRegistersWindow.Update;
  559. begin
  560. ReDraw;
  561. end;
  562. destructor TRegistersWindow.Done;
  563. begin
  564. RegistersWindow:=nil;
  565. inherited done;
  566. end;
  567. {****************************************************************************
  568. TFPUView
  569. ****************************************************************************}
  570. function GetFPURegs(var rs : TFPURegs
  571. {$ifndef cpu_known}
  572. ; UseInfoFloat : boolean
  573. {$endif not cpu_known}
  574. ) : boolean;
  575. var
  576. p,po : pchar;
  577. p1 : pchar;
  578. {$ifndef NODEBUG}
  579. reg,value : string;
  580. buffer : array[0..255] of char;
  581. v : string;
  582. res : cardinal;
  583. i : longint;
  584. err : word;
  585. {$endif}
  586. begin
  587. GetFPURegs:=false;
  588. {$ifndef NODEBUG}
  589. {$ifndef cpu_known}
  590. if UseInfoFloat then
  591. begin
  592. Debugger^.Command('info float');
  593. if Debugger^.Error then
  594. begin
  595. UseInfofloat:=false;
  596. Debugger^.Command('info all');
  597. end;
  598. end
  599. else
  600. {$endif not cpu_known}
  601. Debugger^.Command('info all');
  602. if Debugger^.Error then
  603. exit
  604. else
  605. begin
  606. po:=StrNew(Debugger^.GetOutput);
  607. p:=po;
  608. {$ifndef cpu_known}
  609. i:=0;
  610. {$endif not cpu_known}
  611. if assigned(p) then
  612. begin
  613. fillchar(rs,sizeof(rs),0);
  614. p1:=strscan(p,' ');
  615. while assigned(p1) do
  616. begin
  617. strlcopy(buffer,p,p1-p);
  618. reg:=strpas(buffer);
  619. {$ifndef cpu_known}
  620. p1:=strscan(p,#10);
  621. if assigned(p1) then
  622. begin
  623. strlcopy(buffer,p,p1-p);
  624. rs.freg[i]:=ExtractTabs(strpas(buffer),8);
  625. if i<MaxRegs-1 then
  626. inc(i);
  627. end;
  628. {$else cpu_known}
  629. p:=p1;
  630. while p^=' ' do
  631. inc(p);
  632. if p^='$' then
  633. p1:=strscan(p,#9)
  634. else
  635. p1:=strscan(p,#10);
  636. strlcopy(buffer,p,p1-p);
  637. v:=strpas(buffer);
  638. for i:=1 to length(v) do
  639. if v[i]=#9 then
  640. v[i]:=' ';
  641. val(v,res,err);
  642. {$ifdef i386}
  643. if reg='st0' then
  644. rs.st0:=v
  645. else if reg='st1' then
  646. rs.st1:=v
  647. else if reg='st2' then
  648. rs.st2:=v
  649. else if reg='st3' then
  650. rs.st3:=v
  651. else if reg='st4' then
  652. rs.st4:=v
  653. else if reg='st5' then
  654. rs.st5:=v
  655. else if reg='st6' then
  656. rs.st6:=v
  657. else if reg='st7' then
  658. rs.st7:=v
  659. else if reg='ftag' then
  660. rs.ftag:=res
  661. else if reg='fctrl' then
  662. rs.fctrl:=res
  663. else if reg='fstat' then
  664. rs.fstat:=res
  665. else if reg='fiseg' then
  666. rs.fiseg:=res
  667. else if reg='fioff' then
  668. rs.fioff:=res
  669. else if reg='foseg' then
  670. rs.foseg:=res
  671. else if reg='fooff' then
  672. rs.fooff:=res
  673. else if reg='fop' then
  674. rs.fop:=res;
  675. {$endif i386}
  676. {$ifdef m68k}
  677. if reg='fp0' then
  678. rs.fp0:=v
  679. else if reg='fp1' then
  680. rs.fp1:=v
  681. else if reg='fp2' then
  682. rs.fp2:=v
  683. else if reg='fp3' then
  684. rs.fp3:=v
  685. else if reg='fp4' then
  686. rs.fp4:=v
  687. else if reg='fp5' then
  688. rs.fp5:=v
  689. else if reg='fp6' then
  690. rs.fp6:=v
  691. else if reg='fp7' then
  692. rs.fp7:=v
  693. else if reg='fpcontrol' then
  694. rs.fpcontrol:=res
  695. else if reg='fpstatus' then
  696. rs.fpstatus:=res
  697. else if reg='fpiaddr' then
  698. rs.fpiaddr:=res;
  699. {$endif m68k}
  700. {$ifdef powerpc}
  701. if reg[1]='f' then
  702. for i:=0 to 31 do
  703. if reg='f'+inttostr(i) then
  704. rs.f[i]:=v;
  705. {$endif powerpc}
  706. {$endif cpu_known}
  707. p:=strscan(p1,#10);
  708. if assigned(p) then
  709. begin
  710. p1:=strscan(p,' ');
  711. inc(p);
  712. end
  713. else
  714. break;
  715. end;
  716. { free allocated memory }
  717. strdispose(po);
  718. end
  719. else
  720. exit;
  721. end;
  722. { do not open a messagebox for such errors }
  723. Debugger^.got_error:=false;
  724. GetFPURegs:=true;
  725. {$endif}
  726. end;
  727. constructor TFPUView.Init(var Bounds: TRect);
  728. begin
  729. inherited init(Bounds);
  730. GrowMode:=gfGrowHiX or GfGrowHiY;
  731. InDraw:=false;
  732. FillChar(OldReg,Sizeof(oldreg),#0);
  733. FillChar(NewReg,Sizeof(newreg),#0);
  734. GDBCount:=-1;
  735. {$ifndef cpu_known}
  736. UseInfoFloat:=true;
  737. {$endif not cpu_known}
  738. end;
  739. procedure TFPUView.Draw;
  740. var
  741. rs : tfpuregs;
  742. top : byte;
  743. color :byte;
  744. ok : boolean;
  745. i : byte;
  746. const
  747. TypeStr : Array[0..3] of string[6] =
  748. ('Valid ','Zero ','Spec ','Empty ');
  749. procedure SetColor(Const x,y : string);
  750. begin
  751. if x=y then
  752. color:=7
  753. else
  754. color:=8;
  755. end;
  756. procedure SetIColor(Const x,y : cardinal);
  757. begin
  758. if x=y then
  759. color:=7
  760. else
  761. color:=8;
  762. end;
  763. begin
  764. inherited draw;
  765. {$ifdef NODEBUG}
  766. WriteStr(1,0,'<no values available>',7);
  767. {$else NODEBUG}
  768. If not assigned(Debugger) then
  769. begin
  770. WriteStr(1,0,'<no values available>',7);
  771. exit;
  772. end;
  773. if InDraw then
  774. exit;
  775. InDraw:=true;
  776. if GDBCount<>Debugger^.RunCount then
  777. begin
  778. OldReg:=NewReg;
  779. OK:=GetFPURegs(rs
  780. {$ifndef cpu_known}
  781. ,UseInfoFloat
  782. {$endif not cpu_known}
  783. );
  784. NewReg:=rs;
  785. GDBCount:=Debugger^.RunCount;
  786. end
  787. else
  788. begin
  789. rs:=newreg;
  790. OK:=true;
  791. end;
  792. if OK then
  793. begin
  794. {$ifdef cpu_known}
  795. {$ifdef i386}
  796. top:=(rs.fstat shr 11) and 7;
  797. SetColor(rs.st0,OldReg.st0);
  798. WriteStr(1,0,'ST0 '+TypeStr[(rs.ftag shr (2*((0+top) and 7))) and 3]+rs.st0,color);
  799. SetColor(rs.st1,OldReg.st1);
  800. WriteStr(1,1,'ST1 '+TypeStr[(rs.ftag shr (2*((1+top) and 7))) and 3]+rs.st1,color);
  801. SetColor(rs.st2,OldReg.st2);
  802. WriteStr(1,2,'ST2 '+TypeStr[(rs.ftag shr (2*((2+top) and 7))) and 3]+rs.st2,color);
  803. SetColor(rs.st3,OldReg.st3);
  804. WriteStr(1,3,'ST3 '+TypeStr[(rs.ftag shr (2*((3+top) and 7))) and 3]+rs.st3,color);
  805. SetColor(rs.st4,OldReg.st4);
  806. WriteStr(1,4,'ST4 '+TypeStr[(rs.ftag shr (2*((4+top) and 7))) and 3]+rs.st4,color);
  807. SetColor(rs.st5,OldReg.st5);
  808. WriteStr(1,5,'ST5 '+TypeStr[(rs.ftag shr (2*((5+top) and 7))) and 3]+rs.st5,color);
  809. SetColor(rs.st6,OldReg.st6);
  810. WriteStr(1,6,'ST6 '+TypeStr[(rs.ftag shr (2*((6+top) and 7))) and 3]+rs.st6,color);
  811. SetColor(rs.st7,OldReg.st7);
  812. WriteStr(1,7,'ST7 '+TypeStr[(rs.ftag shr (2*((7+top) and 7))) and 3]+rs.st7,color);
  813. SetIColor(rs.ftag,OldReg.ftag);
  814. WriteStr(1,8,'FTAG '+hexstr(rs.ftag,4),color);
  815. SetIColor(rs.fctrl,OldReg.fctrl);
  816. WriteStr(13,8,'FCTRL '+hexstr(rs.fctrl,4),color);
  817. SetIColor(rs.fstat,OldReg.fstat);
  818. WriteStr(1,9,'FSTAT '+hexstr(rs.fstat,4),color);
  819. SetIColor(rs.fop,OldReg.fop);
  820. WriteStr(13,9,'FOP '+hexstr(rs.fop,4),color);
  821. if (rs.fiseg<>OldReg.fiseg) or
  822. (rs.fioff<>OldReg.fioff) then
  823. color:=8
  824. else
  825. color:=7;
  826. WriteStr(1,10,'FI '+hexstr(rs.fiseg,4)+':'+hexstr(rs.fioff,8),color);
  827. if (rs.foseg<>OldReg.foseg) or
  828. (rs.fooff<>OldReg.fooff) then
  829. color:=8
  830. else
  831. color:=7;
  832. WriteStr(1,11,'FO '+hexstr(rs.foseg,4)+':'+hexstr(rs.fooff,8),color);
  833. {$endif i386}
  834. {$ifdef m68k}
  835. SetColor(rs.fp0,OldReg.fp0);
  836. WriteStr(1,0,'fp0 '+rs.fp0,color);
  837. SetColor(rs.fp1,OldReg.fp1);
  838. WriteStr(1,1,'fp1 '+rs.fp1,color);
  839. SetColor(rs.fp2,OldReg.fp2);
  840. WriteStr(1,2,'fp2 '+rs.fp2,color);
  841. SetColor(rs.fp3,OldReg.fp3);
  842. WriteStr(1,3,'fp3 '+rs.fp3,color);
  843. SetColor(rs.fp4,OldReg.fp4);
  844. WriteStr(1,4,'fp4 '+rs.fp4,color);
  845. SetColor(rs.fp5,OldReg.fp5);
  846. WriteStr(1,5,'fp5 '+rs.fp5,color);
  847. SetColor(rs.fp6,OldReg.fp6);
  848. WriteStr(1,6,'fp6 '+rs.fp6,color);
  849. SetColor(rs.fp7,OldReg.fp7);
  850. WriteStr(1,7,'fp7 '+rs.fp7,color);
  851. SetIColor(rs.fpcontrol,OldReg.fpcontrol);
  852. WriteStr(1,8,'fpcontrol '+hexstr(rs.fpcontrol,8),color);
  853. SetIColor(rs.fpstatus,OldReg.fpstatus);
  854. WriteStr(1,9,'fpstatus '+hexstr(rs.fpstatus,8),color);
  855. SetIColor(rs.fpiaddr,OldReg.fpiaddr);
  856. WriteStr(1,10,'fpiaddr '+hexstr(rs.fpiaddr,8),color);
  857. {$endif m68k}
  858. {$ifdef powerpc}
  859. for i:=0 to 31 do
  860. begin
  861. SetColor(rs.f[i],OldReg.f[i]);
  862. if i<10 then
  863. WriteStr(1,i,'f'+IntToStr(i)+' '+rs.f[i],color)
  864. else
  865. WriteStr(1,i,'f'+IntToStr(i)+' '+rs.f[i],color);
  866. end;
  867. {$endif powerpc}
  868. {$else not cpu_known}
  869. for i:=0 to MaxRegs-1 do
  870. begin
  871. SetColor(rs.freg[i],OldReg.freg[i]);
  872. WriteStr(1,i,rs.freg[i],color);
  873. end;
  874. {$endif cpu_known}
  875. end
  876. else
  877. WriteStr(0,0,'<debugger error>',7);
  878. InDraw:=false;
  879. {$endif NODEBUG}
  880. end;
  881. destructor TFPUView.Done;
  882. begin
  883. inherited done;
  884. end;
  885. {****************************************************************************
  886. TFPUWindow
  887. ****************************************************************************}
  888. constructor TFPUWindow.Init;
  889. var
  890. R : TRect;
  891. begin
  892. Desktop^.GetExtent(R);
  893. {$ifdef i386}
  894. R.A.X:=R.B.X-44;
  895. R.B.Y:=R.A.Y+14;
  896. {$endif i386}
  897. {$ifdef m68k}
  898. R.A.X:=R.B.X-44;
  899. R.B.Y:=R.A.Y+14;
  900. {$endif m68k}
  901. {$ifdef powerpc}
  902. R.A.X:=R.B.X-44;
  903. R.B.Y:=R.A.Y+33;
  904. {$endif powerpc}
  905. {$ifndef cpu_known}
  906. R.A.X:=R.B.X-44;
  907. R.B.Y:=R.A.Y+33;
  908. {$endif cpu_known}
  909. inherited Init(R,dialog_fpu, wnNoNumber);
  910. Flags:=wfClose or wfMove or wfgrow;
  911. Palette:=wpCyanWindow;
  912. HelpCtx:=hcFPURegisters;
  913. R.Assign(1,1,Size.X-2,Size.Y-2);
  914. RV:=new(PFPUView,init(R));
  915. Insert(RV);
  916. If assigned(FPUWindow) then
  917. dispose(FPUWindow,done);
  918. FPUWindow:=@Self;
  919. Update;
  920. end;
  921. constructor TFPUWindow.Load(var S: TStream);
  922. begin
  923. inherited load(S);
  924. GetSubViewPtr(S,RV);
  925. If assigned(FPUWindow) then
  926. dispose(FPUWindow,done);
  927. FPUWindow:=@Self;
  928. end;
  929. procedure TFPUWindow.Store(var S: TStream);
  930. begin
  931. inherited Store(s);
  932. PutSubViewPtr(S,RV);
  933. end;
  934. procedure TFPUWindow.Update;
  935. begin
  936. ReDraw;
  937. end;
  938. destructor TFPUWindow.Done;
  939. begin
  940. FPUWindow:=nil;
  941. inherited done;
  942. end;
  943. procedure InitRegistersWindow;
  944. begin
  945. if RegistersWindow=nil then
  946. begin
  947. new(RegistersWindow,init);
  948. DeskTop^.Insert(RegistersWindow);
  949. end;
  950. end;
  951. procedure DoneRegistersWindow;
  952. begin
  953. if assigned(RegistersWindow) then
  954. begin
  955. DeskTop^.Delete(RegistersWindow);
  956. RegistersWindow:=nil;
  957. end;
  958. end;
  959. procedure InitFPUWindow;
  960. begin
  961. if FPUWindow=nil then
  962. begin
  963. new(FPUWindow,init);
  964. DeskTop^.Insert(FPUWindow);
  965. end;
  966. end;
  967. procedure DoneFPUWindow;
  968. begin
  969. if assigned(FPUWindow) then
  970. begin
  971. DeskTop^.Delete(FPUWindow);
  972. FPUWindow:=nil;
  973. end;
  974. end;
  975. procedure RegisterFPRegsViews;
  976. begin
  977. RegisterType(RRegistersWindow);
  978. RegisterType(RRegistersView);
  979. RegisterType(RFPUWindow);
  980. RegisterType(RFPUView);
  981. end;
  982. end.
  983. {
  984. $Log$
  985. Revision 1.4 2004-11-11 15:20:52 florian
  986. * applied Peter's patch from yesterday
  987. Revision 1.3 2004/02/06 21:34:43 jonas
  988. * fixed ppc compilation error
  989. Revision 1.2 2002/12/16 15:51:13 pierre
  990. * added unknown cpu register windows
  991. Revision 1.1 2002/12/12 00:01:59 pierre
  992. Register window code separated in a new unit
  993. }