fpregs.pas 32 KB

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