fpregs.pas 32 KB

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