mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 02:28:14 +02:00
1635 lines
48 KiB
ObjectPascal
1635 lines
48 KiB
ObjectPascal
{
|
|
This file is part of the Free Pascal Integrated Development Environment
|
|
Copyright (c) 1998-2000 by Pierre Muller
|
|
|
|
Register debug routines for the IDE
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
unit FPRegs;
|
|
{$ifdef NODEBUG}
|
|
interface
|
|
implementation
|
|
end.
|
|
{$else NODEBUG}
|
|
interface
|
|
uses
|
|
{$ifdef win32}
|
|
Windows,
|
|
{$endif win32}
|
|
Objects,Dialogs,Drivers,Views,
|
|
FPViews;
|
|
|
|
|
|
const
|
|
MaxRegs = 128;
|
|
|
|
type
|
|
|
|
{$ifdef TP}
|
|
dword = longint;
|
|
{$endif TP}
|
|
|
|
{$undef cpu_known}
|
|
|
|
TIntRegs = record
|
|
{$ifndef test_generic_cpu}
|
|
{$ifdef cpui386}
|
|
{$define cpu_known}
|
|
eax,ebx,ecx,edx,eip,esi,edi,esp,ebp : dword;
|
|
cs,ds,es,ss,fs,gs : word;
|
|
eflags : dword;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
{$define cpu_known}
|
|
d0,d1,d2,d3,d4,d5,d6,d7 : dword;
|
|
a0,a1,a2,a3,a4,a5,fp,sp : dword;
|
|
ps,pc : dword;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
{$define cpu_known}
|
|
r : array [0..31] of dword;
|
|
pc,ps,cr,lr,ctr,xer : dword;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
{$define cpu_known}
|
|
o : array [0..7] of dword;
|
|
i : array [0..7] of dword;
|
|
l : array [0..7] of dword;
|
|
g : array [0..7] of dword;
|
|
y,psr,wim,tbr,pc,npc,fsr,csr : dword;
|
|
{$endif cpusparc}
|
|
{$endif not test_generic_cpu}
|
|
{$ifndef cpu_known}
|
|
reg : array [0..MaxRegs-1] of string;
|
|
{$endif not cpu_known}
|
|
end;
|
|
|
|
PRegistersView = ^TRegistersView;
|
|
TRegistersView = object(TView)
|
|
NewReg,OldReg : TIntRegs;
|
|
InDraw : boolean;
|
|
GDBCount : longint;
|
|
first : boolean;
|
|
constructor Init(var Bounds: TRect);
|
|
procedure Draw;virtual;
|
|
destructor Done; virtual;
|
|
end;
|
|
|
|
PRegistersWindow = ^TRegistersWindow;
|
|
TRegistersWindow = Object(TFPDlgWindow)
|
|
RV : PRegistersView;
|
|
Constructor Init;
|
|
constructor Load(var S: TStream);
|
|
procedure Store(var S: TStream);
|
|
procedure Update; virtual;
|
|
destructor Done; virtual;
|
|
end;
|
|
|
|
TFPURegs = record
|
|
{$ifndef test_generic_cpu}
|
|
{$ifdef cpui386}
|
|
st0,st1,st2,st3,st4,st5,st6,st7 :string;
|
|
ftag,fop,fctrl,fstat,fiseg,foseg : word;
|
|
fioff,fooff : cardinal;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
fp0,fp1,fp2,fp3,fp4,fp5,fp6,fp7 : string;
|
|
fpcontrol,fpstatus,fpiaddr : dword;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
f : array [0..31] of string;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
f : array [0..31] of string;
|
|
{$endif cpusparc}
|
|
{$endif not test_generic_cpu}
|
|
{$ifndef cpu_known}
|
|
freg : array [0..MaxRegs-1] of string;
|
|
{$endif not cpu_known}
|
|
end;
|
|
|
|
PFPUView = ^TFPUView;
|
|
TFPUView = object(TView)
|
|
NewReg,OldReg : TFPURegs;
|
|
InDraw : boolean;
|
|
GDBCount : longint;
|
|
{$ifndef cpu_known}
|
|
UseInfoFloat : boolean;
|
|
{$endif not cpu_known}
|
|
first : boolean;
|
|
constructor Init(var Bounds: TRect);
|
|
procedure Draw;virtual;
|
|
destructor Done; virtual;
|
|
end;
|
|
|
|
PFPUWindow = ^TFPUWindow;
|
|
TFPUWindow = Object(TFPDlgWindow)
|
|
RV : PFPUView;
|
|
Constructor Init;
|
|
constructor Load(var S: TStream);
|
|
procedure Store(var S: TStream);
|
|
procedure Update; virtual;
|
|
destructor Done; virtual;
|
|
end;
|
|
|
|
tssereg = record
|
|
case byte of
|
|
1 : (bytearray : array[0..15] of byte);
|
|
2 : (wordarray : array[0..7] of word);
|
|
3 : (dwordarray : array[0..3] of dword);
|
|
4 : (qwordarray : array[0..1] of qword);
|
|
5 : (twordfield : array[0..1] of qword);
|
|
6 : (singlearray : array[0..3] of single);
|
|
7 : (doublearray : array[0..1] of double);
|
|
end;
|
|
|
|
tmmxreg = record
|
|
case byte of
|
|
1 : (bytearray : array[0..7] of byte);
|
|
2 : (wordarray : array[0..3] of word);
|
|
3 : (dwordarray : array[0..1] of dword);
|
|
4 : (qwordfield : qword);
|
|
6 : (singlearray : array[0..1] of single);
|
|
end;
|
|
|
|
TVectorRegs = record
|
|
{$ifndef test_generic_cpu}
|
|
{$ifdef cpui386}
|
|
xmm : array[0..7] of string;
|
|
mmx : array[0..7] of string;
|
|
mxcsr : string;
|
|
{$endif cpui386}
|
|
{$ifdef cpupowerpc}
|
|
m : array[0..31] of string;
|
|
{$endif cpupowerpc}
|
|
{$endif not test_generic_cpu}
|
|
{$ifndef cpu_known}
|
|
vreg : array [0..MaxRegs-1] of string;
|
|
{$endif not cpu_known}
|
|
end;
|
|
|
|
|
|
PVectorView = ^TVectorView;
|
|
TVectorView = object(TView)
|
|
NewReg,OldReg : TVectorRegs;
|
|
InDraw : boolean;
|
|
GDBCount : longint;
|
|
{$ifndef cpu_known}
|
|
UseInfoVector : boolean;
|
|
{$endif not cpu_known}
|
|
first : boolean;
|
|
constructor Init(var Bounds: TRect);
|
|
procedure Draw;virtual;
|
|
destructor Done; virtual;
|
|
end;
|
|
|
|
PVectorWindow = ^TVectorWindow;
|
|
TVectorWindow = Object(TFPDlgWindow)
|
|
RV : PVectorView;
|
|
Constructor Init;
|
|
constructor Load(var S: TStream);
|
|
procedure Store(var S: TStream);
|
|
procedure Update; virtual;
|
|
destructor Done; virtual;
|
|
end;
|
|
|
|
|
|
procedure InitRegistersWindow;
|
|
procedure DoneRegistersWindow;
|
|
procedure InitFPUWindow;
|
|
procedure DoneFPUWindow;
|
|
procedure InitVectorWindow;
|
|
procedure DoneVectorWindow;
|
|
|
|
procedure RegisterFPRegsViews;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
Strings,
|
|
{$ifndef NODEBUG}
|
|
GDBCon,GDBInt,
|
|
{$endif NODEBUG}
|
|
App,Menus,
|
|
WViews,WEditor,
|
|
wutils,
|
|
FPConst,FPVars,
|
|
FPString,
|
|
FPDebug;
|
|
|
|
|
|
Const
|
|
RRegistersWindow: TStreamRec = (
|
|
ObjType: 1711;
|
|
VmtLink: Ofs(TypeOf(TRegistersWindow)^);
|
|
Load: @TRegistersWindow.Load;
|
|
Store: @TRegistersWindow.Store
|
|
);
|
|
|
|
RRegistersView: TStreamRec = (
|
|
ObjType: 1712;
|
|
VmtLink: Ofs(TypeOf(TRegistersView)^);
|
|
Load: @TRegistersView.Load;
|
|
Store: @TRegistersView.Store
|
|
);
|
|
|
|
RFPUWindow: TStreamRec = (
|
|
ObjType: 1713;
|
|
VmtLink: Ofs(TypeOf(TFPUWindow)^);
|
|
Load: @TFPUWindow.Load;
|
|
Store: @TFPUWindow.Store
|
|
);
|
|
|
|
RFPUView: TStreamRec = (
|
|
ObjType: 1714;
|
|
VmtLink: Ofs(TypeOf(TFPUView)^);
|
|
Load: @TFPUView.Load;
|
|
Store: @TFPUView.Store
|
|
);
|
|
|
|
RVectorView: TStreamRec = (
|
|
ObjType: 1715;
|
|
VmtLink: Ofs(TypeOf(TVectorView)^);
|
|
Load: @TVectorView.Load;
|
|
Store: @TVectorView.Store
|
|
);
|
|
|
|
|
|
{****************************************************************************
|
|
TRegistersView
|
|
****************************************************************************}
|
|
|
|
function GetIntRegs(var rs : TIntRegs) : boolean;
|
|
|
|
var
|
|
p,po : pchar;
|
|
p1 : pchar;
|
|
reg,value : string;
|
|
buffer : array[0..255] of char;
|
|
v : dword;
|
|
code : word;
|
|
i : byte;
|
|
|
|
begin
|
|
GetIntRegs:=false;
|
|
{$ifndef NODEBUG}
|
|
Debugger^.Command('info registers');
|
|
if Debugger^.Error then
|
|
exit
|
|
else
|
|
begin
|
|
{$ifndef cpu_known}
|
|
i:=0;
|
|
{$endif not cpu_known}
|
|
po:=StrNew(Debugger^.GetOutput);
|
|
p:=po;
|
|
if assigned(p) then
|
|
begin
|
|
fillchar(rs,sizeof(rs),0);
|
|
p1:=strscan(p,' ');
|
|
while assigned(p1) do
|
|
begin
|
|
{$ifndef cpu_known}
|
|
p1:=strscan(p,#10);
|
|
if assigned(p1) then
|
|
begin
|
|
strlcopy(buffer,p,p1-p);
|
|
rs.reg[i]:=ExtractTabs(strpas(buffer),8);
|
|
if i<MaxRegs-1 then
|
|
inc(i);
|
|
end;
|
|
{$else cpu_known}
|
|
strlcopy(buffer,p,p1-p);
|
|
reg:=strpas(buffer);
|
|
p1:=strscan(p,'$');
|
|
{ some targets use 0x instead of $ }
|
|
if p1=nil then
|
|
p:=strpos(p,'0x')
|
|
else
|
|
p:=p1;
|
|
p1:=strscan(p,#9);
|
|
strlcopy(buffer,p,p1-p);
|
|
value:=strpas(buffer);
|
|
|
|
{ replace the $? }
|
|
if copy(value,1,2)='0x' then
|
|
value:='$'+copy(value,3,length(value)-2);
|
|
val(value,v,code);
|
|
{$ifdef cpui386}
|
|
if reg='eax' then
|
|
rs.eax:=v
|
|
else if reg='ebx' then
|
|
rs.ebx:=v
|
|
else if reg='ecx' then
|
|
rs.ecx:=v
|
|
else if reg='edx' then
|
|
rs.edx:=v
|
|
else if reg='eip' then
|
|
rs.eip:=v
|
|
else if reg='esi' then
|
|
rs.esi:=v
|
|
else if reg='edi' then
|
|
rs.edi:=v
|
|
else if reg='esp' then
|
|
rs.esp:=v
|
|
else if reg='ebp' then
|
|
rs.ebp:=v
|
|
{ under win32 flags are on a register named ps !! PM }
|
|
else if (reg='eflags') or (reg='ps') then
|
|
rs.eflags:=v
|
|
else if reg='cs' then
|
|
rs.cs:=v
|
|
else if reg='ds' then
|
|
rs.ds:=v
|
|
else if reg='es' then
|
|
rs.es:=v
|
|
else if reg='fs' then
|
|
rs.fs:=v
|
|
else if reg='gs' then
|
|
rs.gs:=v
|
|
else if reg='ss' then
|
|
rs.ss:=v;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
if reg='d0' then
|
|
rs.d0:=v
|
|
else if reg='d1' then
|
|
rs.d1:=v
|
|
else if reg='d2' then
|
|
rs.d2:=v
|
|
else if reg='d3' then
|
|
rs.d3:=v
|
|
else if reg='d4' then
|
|
rs.d4:=v
|
|
else if reg='d5' then
|
|
rs.d5:=v
|
|
else if reg='d6' then
|
|
rs.d6:=v
|
|
else if reg='d7' then
|
|
rs.d7:=v
|
|
else if reg='a0' then
|
|
rs.a0:=v
|
|
else if reg='a1' then
|
|
rs.a1:=v
|
|
else if reg='a2' then
|
|
rs.a2:=v
|
|
else if reg='a3' then
|
|
rs.a3:=v
|
|
else if reg='a4' then
|
|
rs.a4:=v
|
|
else if reg='a5' then
|
|
rs.a5:=v
|
|
else if reg='fp' then
|
|
rs.fp:=v
|
|
else if reg='sp' then
|
|
rs.sp:=v
|
|
else if (reg='ps') then
|
|
rs.ps:=v
|
|
else if reg='pc' then
|
|
rs.pc:=v;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
if (reg[1]='r') then
|
|
begin
|
|
for i:=0 to 31 do
|
|
if reg='r'+inttostr(i) then
|
|
rs.r[i]:=v;
|
|
end
|
|
{ other regs
|
|
pc,ps,cr,lr,ctr,xer : dword; }
|
|
else if (reg='pc') then
|
|
rs.pc:=v
|
|
else if (reg='ps') then
|
|
rs.ps:=v
|
|
else if (reg='lr') then
|
|
rs.lr:=v
|
|
else if (reg='ctr') then
|
|
rs.ctr:=v
|
|
else if (reg='xer') then
|
|
rs.xer:=v;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
if (reg[1]='o') then
|
|
begin
|
|
for i:=0 to 7 do
|
|
if reg='o'+inttostr(i) then
|
|
rs.o[i]:=v;
|
|
end
|
|
else if (reg[1]='i') then
|
|
begin
|
|
for i:=0 to 7 do
|
|
if reg='i'+inttostr(i) then
|
|
rs.i[i]:=v;
|
|
end
|
|
else if (reg[1]='l') then
|
|
begin
|
|
for i:=0 to 7 do
|
|
if reg='l'+inttostr(i) then
|
|
rs.l[i]:=v;
|
|
end
|
|
else if (reg[1]='g') then
|
|
begin
|
|
for i:=0 to 7 do
|
|
if reg='g'+inttostr(i) then
|
|
rs.g[i]:=v;
|
|
end
|
|
|
|
else if reg='fp' then
|
|
rs.i[6]:=v
|
|
else if reg='y' then
|
|
rs.y:=v
|
|
else if reg='psr' then
|
|
rs.psr:=v
|
|
else if reg='wim' then
|
|
rs.wim:=v
|
|
else if reg='tbs' then
|
|
rs.tbr:=v
|
|
else if reg='pc' then
|
|
rs.pc:=v
|
|
else if reg='npc' then
|
|
rs.npc:=v
|
|
else if reg='fsr' then
|
|
rs.fsr:=v
|
|
else if reg='csr' then
|
|
rs.csr:=v;
|
|
{$endif cpusparc}
|
|
{$endif not cpu_known}
|
|
p:=strscan(p1,#10);
|
|
if assigned(p) then
|
|
begin
|
|
p1:=strscan(p,' ');
|
|
inc(p);
|
|
end
|
|
else
|
|
break;
|
|
end;
|
|
{ free allocated memory }
|
|
strdispose(po);
|
|
end
|
|
else
|
|
exit;
|
|
end;
|
|
{ do not open a messagebox for such errors }
|
|
Debugger^.got_error:=false;
|
|
GetIntRegs:=true;
|
|
{$endif}
|
|
end;
|
|
|
|
constructor TRegistersView.Init(var Bounds: TRect);
|
|
|
|
begin
|
|
inherited init(Bounds);
|
|
InDraw:=false;
|
|
first:=true;
|
|
FillChar(OldReg,Sizeof(OldReg),#0);
|
|
FillChar(NewReg,Sizeof(NewReg),#0);
|
|
GrowMode:=gfGrowHiX or GfGrowHiY;
|
|
GDBCount:=-1;
|
|
end;
|
|
|
|
procedure TRegistersView.Draw;
|
|
|
|
var
|
|
rs : tintregs;
|
|
OK : boolean;
|
|
color :byte;
|
|
i : byte;
|
|
|
|
procedure SetColor(x,y : longint);
|
|
begin
|
|
if x=y then
|
|
color:=7
|
|
else
|
|
color:=8;
|
|
end;
|
|
|
|
procedure SetStrColor(const x,y : string);
|
|
begin
|
|
if x=y then
|
|
color:=7
|
|
else
|
|
color:=8;
|
|
end;
|
|
|
|
begin
|
|
inherited draw;
|
|
{$ifdef NODEBUG}
|
|
WriteStr(1,0,'<no values available>',7);
|
|
{$else NODEBUG}
|
|
If not assigned(Debugger) then
|
|
begin
|
|
WriteStr(1,0,'<no values available>',7);
|
|
exit;
|
|
end;
|
|
if InDraw then exit;
|
|
InDraw:=true;
|
|
if GDBCount<>Debugger^.RunCount then
|
|
begin
|
|
OldReg:=NewReg;
|
|
OK:=GetIntRegs(rs);
|
|
NewReg:=rs;
|
|
{ get inital values }
|
|
if first then
|
|
begin
|
|
OldReg:=NewReg;
|
|
first:=false;
|
|
end;
|
|
GDBCount:=Debugger^.RunCount;
|
|
end
|
|
else
|
|
begin
|
|
rs:=NewReg;
|
|
OK:=true;
|
|
end;
|
|
if OK then
|
|
begin
|
|
{$ifdef cpu_known}
|
|
{$ifdef cpui386}
|
|
SetColor(rs.eax,OldReg.eax);
|
|
WriteStr(1,0,'EAX '+HexStr(longint(rs.eax),8),color);
|
|
SetColor(rs.ebx,OldReg.ebx);
|
|
WriteStr(1,1,'EBX '+HexStr(longint(rs.ebx),8),color);
|
|
SetColor(rs.ecx,OldReg.ecx);
|
|
WriteStr(1,2,'ECX '+HexStr(longint(rs.ecx),8),color);
|
|
SetColor(rs.edx,OldReg.edx);
|
|
WriteStr(1,3,'EDX '+HexStr(longint(rs.edx),8),color);
|
|
SetColor(rs.eip,OldReg.eip);
|
|
WriteStr(1,4,'EIP '+HexStr(longint(rs.eip),8),color);
|
|
SetColor(rs.esi,OldReg.esi);
|
|
WriteStr(1,5,'ESI '+HexStr(longint(rs.esi),8),color);
|
|
SetColor(rs.edi,OldReg.edi);
|
|
WriteStr(1,6,'EDI '+HexStr(longint(rs.edi),8),color);
|
|
SetColor(rs.esp,OldReg.esp);
|
|
WriteStr(1,7,'ESP '+HexStr(longint(rs.esp),8),color);
|
|
SetColor(rs.ebp,OldReg.ebp);
|
|
WriteStr(1,8,'EBP '+HexStr(longint(rs.ebp),8),color);
|
|
SetColor(rs.cs,OldReg.cs);
|
|
WriteStr(14,0,'CS '+HexStr(rs.cs,4),color);
|
|
SetColor(rs.ds,OldReg.ds);
|
|
WriteStr(14,1,'DS '+HexStr(rs.ds,4),color);
|
|
SetColor(rs.es,OldReg.es);
|
|
WriteStr(14,2,'ES '+HexStr(rs.es,4),color);
|
|
SetColor(rs.fs,OldReg.fs);
|
|
WriteStr(14,3,'FS '+HexStr(rs.fs,4),color);
|
|
SetColor(rs.gs,OldReg.gs);
|
|
WriteStr(14,4,'GS '+HexStr(rs.gs,4),color);
|
|
SetColor(rs.ss,OldReg.ss);
|
|
WriteStr(14,5,'SS '+HexStr(rs.ss,4),color);
|
|
SetColor(rs.eflags and $1,OldReg.eflags and $1);
|
|
WriteStr(22,0,'c='+chr(byte((rs.eflags and $1)<>0)+48),color);
|
|
SetColor(rs.eflags and $20,OldReg.eflags and $20);
|
|
WriteStr(22,1,'z='+chr(byte((rs.eflags and $20)<>0)+48),color);
|
|
SetColor(rs.eflags and $80,OldReg.eflags and $80);
|
|
WriteStr(22,2,'s='+chr(byte((rs.eflags and $80)<>0)+48),color);
|
|
SetColor(rs.eflags and $800,OldReg.eflags and $800);
|
|
WriteStr(22,3,'o='+chr(byte((rs.eflags and $800)<>0)+48),color);
|
|
SetColor(rs.eflags and $4,OldReg.eflags and $4);
|
|
WriteStr(22,4,'p='+chr(byte((rs.eflags and $4)<>0)+48),color);
|
|
SetColor(rs.eflags and $200,OldReg.eflags and $200);
|
|
WriteStr(22,5,'i='+chr(byte((rs.eflags and $200)<>0)+48),color);
|
|
SetColor(rs.eflags and $10,OldReg.eflags and $10);
|
|
WriteStr(22,6,'a='+chr(byte((rs.eflags and $10)<>0)+48),color);
|
|
SetColor(rs.eflags and $400,OldReg.eflags and $400);
|
|
WriteStr(22,7,'d='+chr(byte((rs.eflags and $400)<>0)+48),color);
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
SetColor(rs.d0,OldReg.d0);
|
|
WriteStr(1,0,'d0 '+HexStr(longint(rs.d0),8),color);
|
|
SetColor(rs.d1,OldReg.d1);
|
|
WriteStr(1,1,'d1 '+HexStr(longint(rs.d1),8),color);
|
|
SetColor(rs.d2,OldReg.d2);
|
|
WriteStr(1,2,'d2 '+HexStr(longint(rs.d2),8),color);
|
|
SetColor(rs.d3,OldReg.d3);
|
|
WriteStr(1,3,'d3 '+HexStr(longint(rs.d3),8),color);
|
|
SetColor(rs.d4,OldReg.d4);
|
|
WriteStr(1,4,'d4 '+HexStr(longint(rs.d4),8),color);
|
|
SetColor(rs.d5,OldReg.d5);
|
|
WriteStr(1,5,'d5 '+HexStr(longint(rs.d5),8),color);
|
|
SetColor(rs.d6,OldReg.d6);
|
|
WriteStr(1,6,'d6 '+HexStr(longint(rs.d6),8),color);
|
|
SetColor(rs.d7,OldReg.d7);
|
|
WriteStr(1,7,'d7 '+HexStr(longint(rs.d7),8),color);
|
|
SetColor(rs.a0,OldReg.a0);
|
|
WriteStr(14,0,'a0 '+HexStr(longint(rs.a0),8),color);
|
|
SetColor(rs.a1,OldReg.a1);
|
|
WriteStr(14,1,'a1 '+HexStr(longint(rs.a1),8),color);
|
|
SetColor(rs.a2,OldReg.a2);
|
|
WriteStr(14,2,'a2 '+HexStr(longint(rs.a2),8),color);
|
|
SetColor(rs.a3,OldReg.a3);
|
|
WriteStr(14,3,'a3 '+HexStr(longint(rs.a3),8),color);
|
|
SetColor(rs.a4,OldReg.a4);
|
|
WriteStr(14,4,'a4 '+HexStr(longint(rs.a4),8),color);
|
|
SetColor(rs.a5,OldReg.a5);
|
|
WriteStr(14,5,'a5 '+HexStr(longint(rs.a5),8),color);
|
|
SetColor(rs.fp,OldReg.fp);
|
|
WriteStr(14,6,'fp '+HexStr(longint(rs.fp),8),color);
|
|
SetColor(rs.sp,OldReg.sp);
|
|
WriteStr(14,7,'sp '+HexStr(longint(rs.sp),8),color);
|
|
SetColor(rs.pc,OldReg.pc);
|
|
WriteStr(1,8,'pc '+HexStr(longint(rs.pc),8),color);
|
|
SetColor(rs.ps and $1,OldReg.ps and $1);
|
|
WriteStr(22,8,' c'+chr(byte((rs.ps and $1)<>0)+48),color);
|
|
SetColor(rs.ps and $2,OldReg.ps and $2);
|
|
WriteStr(19,8,' v'+chr(byte((rs.ps and $2)<>0)+48),color);
|
|
SetColor(rs.ps and $4,OldReg.ps and $4);
|
|
WriteStr(16,8,' z'+chr(byte((rs.ps and $4)<>0)+48),color);
|
|
SetColor(rs.ps and $8,OldReg.ps and $8);
|
|
WriteStr(14,8, 'x'+chr(byte((rs.ps and $8)<>0)+48),color);
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
for i:=0 to 15 do
|
|
begin
|
|
SetColor(rs.r[i],OldReg.r[i]);
|
|
if i<10 then
|
|
WriteStr(1,i,'r'+IntToStr(i)+' '+HexStr(longint(rs.r[i]),8),color)
|
|
else
|
|
WriteStr(1,i,'r'+IntToStr(i)+' '+HexStr(longint(rs.r[i]),8),color);
|
|
end;
|
|
for i:=16 to 31 do
|
|
begin
|
|
SetColor(rs.r[i],OldReg.r[i]);
|
|
WriteStr(15,i-16,'r'+IntToStr(i)+' '+HexStr(longint(rs.r[i]),8),color);
|
|
end;
|
|
{ other regs pc,ps,cr,lr,ctr,xer : dword; }
|
|
SetColor(rs.pc,OldReg.pc);
|
|
WriteStr(1,16,'pc '+HexStr(longint(rs.pc),8),color);
|
|
SetColor(rs.ps,OldReg.ps);
|
|
WriteStr(15,16,'ps '+HexStr(longint(rs.ps),8),color);
|
|
SetColor(rs.lr,OldReg.lr);
|
|
WriteStr(1,17,'lr '+HexStr(longint(rs.lr),8),color);
|
|
SetColor(rs.ctr,OldReg.ctr);
|
|
WriteStr(15,17,'ctr '+HexStr(longint(rs.ctr),8),color);
|
|
SetColor(rs.xer,OldReg.xer);
|
|
WriteStr(15,18,'xer '+HexStr(longint(rs.xer),8),color);
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
for i:=0 to 7 do
|
|
begin
|
|
SetColor(rs.g[i],OldReg.g[i]);
|
|
WriteStr(1,i,'g'+IntToStr(i)+' '+HexStr(longint(rs.g[i]),8),color);
|
|
SetColor(rs.l[i],OldReg.l[i]);
|
|
WriteStr(1,i+8,'l'+IntToStr(i)+' '+HexStr(longint(rs.l[i]),8),color);
|
|
end;
|
|
for i:=0 to 7 do
|
|
begin
|
|
SetColor(rs.i[i],OldReg.i[i]);
|
|
if i=6 then
|
|
WriteStr(15,i,'fp '+HexStr(longint(rs.i[i]),8),color)
|
|
else
|
|
WriteStr(15,i,'i'+IntToStr(i)+' '+HexStr(longint(rs.i[i]),8),color);
|
|
SetColor(rs.o[i],OldReg.o[i]);
|
|
WriteStr(15,i+8,'o'+IntToStr(i)+' '+HexStr(longint(rs.o[i]),8),color);
|
|
end;
|
|
SetColor(rs.pc,OldReg.pc);
|
|
WriteStr(1,16,'pc '+HexStr(longint(rs.pc),8),color);
|
|
SetColor(rs.y,OldReg.y);
|
|
WriteStr(1,17,'y '+HexStr(longint(rs.y),8),color);
|
|
SetColor(rs.psr,OldReg.psr);
|
|
WriteStr(1,18,'psr '+HexStr(longint(rs.psr),8),color);
|
|
SetColor(rs.csr,OldReg.csr);
|
|
WriteStr(1,19,'csr '+HexStr(longint(rs.csr),8),color);
|
|
SetColor(rs.npc,OldReg.npc);
|
|
WriteStr(15,16,'npc '+HexStr(longint(rs.npc),8),color);
|
|
SetColor(rs.tbr,OldReg.tbr);
|
|
WriteStr(15,17,'tbr '+HexStr(longint(rs.tbr),8),color);
|
|
SetColor(rs.wim,OldReg.wim);
|
|
WriteStr(15,18,'wim '+HexStr(longint(rs.wim),8),color);
|
|
SetColor(rs.fsr,OldReg.fsr);
|
|
WriteStr(15,19,'fsr '+HexStr(longint(rs.fsr),8),color);
|
|
{$endif cpusparc}
|
|
{$else cpu_known}
|
|
for i:=0 to MaxRegs-1 do
|
|
begin
|
|
SetStrColor(rs.reg[i],OldReg.reg[i]);
|
|
WriteStr(1,i,rs.reg[i],color);
|
|
end;
|
|
{$endif cpu_known}
|
|
end
|
|
else
|
|
WriteStr(0,0,'<debugger error>',7);
|
|
InDraw:=false;
|
|
{$endif NODEBUG}
|
|
end;
|
|
|
|
destructor TRegistersView.Done;
|
|
|
|
begin
|
|
inherited done;
|
|
end;
|
|
|
|
{****************************************************************************
|
|
TRegistersWindow
|
|
****************************************************************************}
|
|
|
|
constructor TRegistersWindow.Init;
|
|
|
|
var
|
|
R : TRect;
|
|
|
|
begin
|
|
Desktop^.GetExtent(R);
|
|
{$ifdef cpui386}
|
|
R.A.X:=R.B.X-28;
|
|
R.B.Y:=R.A.Y+11;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
R.A.X:=R.B.X-28;
|
|
R.B.Y:=R.A.Y+11;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
R.A.X:=R.B.X-28;
|
|
R.B.Y:=R.A.Y+22;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
R.A.X:=R.B.X-30;
|
|
R.B.Y:=R.A.Y+22;
|
|
{$endif cpusparc}
|
|
{$ifndef cpu_known}
|
|
R.A.X:=R.B.X-28;
|
|
R.B.Y:=R.A.Y+22;
|
|
{$endif cpu_known}
|
|
inherited Init(R,dialog_registers, wnNoNumber);
|
|
Flags:=wfClose or wfMove;
|
|
{$ifndef cpu_known}
|
|
Flags:=Flags or wfgrow;
|
|
{$endif cpu_known}
|
|
Palette:=wpCyanWindow;
|
|
HelpCtx:=hcRegistersWindow;
|
|
R.Assign(1,1,Size.X-2,Size.Y-1);
|
|
RV:=new(PRegistersView,init(R));
|
|
Insert(RV);
|
|
If assigned(RegistersWindow) then
|
|
dispose(RegistersWindow,done);
|
|
RegistersWindow:=@Self;
|
|
Update;
|
|
end;
|
|
|
|
constructor TRegistersWindow.Load(var S: TStream);
|
|
|
|
begin
|
|
inherited load(S);
|
|
GetSubViewPtr(S,RV);
|
|
If assigned(RegistersWindow) then
|
|
dispose(RegistersWindow,done);
|
|
RegistersWindow:=@Self;
|
|
end;
|
|
|
|
procedure TRegistersWindow.Store(var S: TStream);
|
|
|
|
begin
|
|
inherited Store(s);
|
|
PutSubViewPtr(S,RV);
|
|
end;
|
|
|
|
procedure TRegistersWindow.Update;
|
|
|
|
begin
|
|
ReDraw;
|
|
end;
|
|
|
|
destructor TRegistersWindow.Done;
|
|
|
|
begin
|
|
RegistersWindow:=nil;
|
|
inherited done;
|
|
end;
|
|
|
|
{****************************************************************************
|
|
TFPUView
|
|
****************************************************************************}
|
|
|
|
function GetFPURegs(var rs : TFPURegs
|
|
{$ifndef cpu_known}
|
|
; UseInfoFloat : boolean
|
|
{$endif not cpu_known}
|
|
) : boolean;
|
|
|
|
var
|
|
p,po : pchar;
|
|
p1 : pchar;
|
|
{$ifndef NODEBUG}
|
|
reg,value : string;
|
|
buffer : array[0..255] of char;
|
|
v : string;
|
|
res : cardinal;
|
|
i : longint;
|
|
err : word;
|
|
{$endif}
|
|
|
|
begin
|
|
GetFPURegs:=false;
|
|
{$ifndef NODEBUG}
|
|
{$ifndef cpu_known}
|
|
if UseInfoFloat then
|
|
begin
|
|
Debugger^.Command('info float');
|
|
if Debugger^.Error then
|
|
begin
|
|
UseInfofloat:=false;
|
|
Debugger^.Command('info all');
|
|
end;
|
|
end
|
|
else
|
|
{$endif not cpu_known}
|
|
Debugger^.Command('info all');
|
|
if Debugger^.Error then
|
|
exit
|
|
else
|
|
begin
|
|
po:=StrNew(Debugger^.GetOutput);
|
|
p:=po;
|
|
{$ifndef cpu_known}
|
|
i:=0;
|
|
{$endif not cpu_known}
|
|
if assigned(p) then
|
|
begin
|
|
fillchar(rs,sizeof(rs),0);
|
|
p1:=strscan(p,' ');
|
|
while assigned(p1) do
|
|
begin
|
|
strlcopy(buffer,p,p1-p);
|
|
reg:=strpas(buffer);
|
|
{$ifndef cpu_known}
|
|
p1:=strscan(p,#10);
|
|
if assigned(p1) then
|
|
begin
|
|
strlcopy(buffer,p,p1-p);
|
|
rs.freg[i]:=ExtractTabs(strpas(buffer),8);
|
|
if i<MaxRegs-1 then
|
|
inc(i);
|
|
end;
|
|
{$else cpu_known}
|
|
p:=p1;
|
|
while p^=' ' do
|
|
inc(p);
|
|
if p^='$' then
|
|
p1:=strscan(p,#9)
|
|
else
|
|
p1:=strscan(p,#10);
|
|
strlcopy(buffer,p,p1-p);
|
|
v:=strpas(buffer);
|
|
for i:=1 to length(v) do
|
|
if v[i]=#9 then
|
|
v[i]:=' ';
|
|
val(v,res,err);
|
|
{$ifdef cpui386}
|
|
if reg='st0' then
|
|
rs.st0:=v
|
|
else if reg='st1' then
|
|
rs.st1:=v
|
|
else if reg='st2' then
|
|
rs.st2:=v
|
|
else if reg='st3' then
|
|
rs.st3:=v
|
|
else if reg='st4' then
|
|
rs.st4:=v
|
|
else if reg='st5' then
|
|
rs.st5:=v
|
|
else if reg='st6' then
|
|
rs.st6:=v
|
|
else if reg='st7' then
|
|
rs.st7:=v
|
|
else if reg='ftag' then
|
|
rs.ftag:=res
|
|
else if reg='fctrl' then
|
|
rs.fctrl:=res
|
|
else if reg='fstat' then
|
|
rs.fstat:=res
|
|
else if reg='fiseg' then
|
|
rs.fiseg:=res
|
|
else if reg='fioff' then
|
|
rs.fioff:=res
|
|
else if reg='foseg' then
|
|
rs.foseg:=res
|
|
else if reg='fooff' then
|
|
rs.fooff:=res
|
|
else if reg='fop' then
|
|
rs.fop:=res;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
if reg='fp0' then
|
|
rs.fp0:=v
|
|
else if reg='fp1' then
|
|
rs.fp1:=v
|
|
else if reg='fp2' then
|
|
rs.fp2:=v
|
|
else if reg='fp3' then
|
|
rs.fp3:=v
|
|
else if reg='fp4' then
|
|
rs.fp4:=v
|
|
else if reg='fp5' then
|
|
rs.fp5:=v
|
|
else if reg='fp6' then
|
|
rs.fp6:=v
|
|
else if reg='fp7' then
|
|
rs.fp7:=v
|
|
else if reg='fpcontrol' then
|
|
rs.fpcontrol:=res
|
|
else if reg='fpstatus' then
|
|
rs.fpstatus:=res
|
|
else if reg='fpiaddr' then
|
|
rs.fpiaddr:=res;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
if reg[1]='f' then
|
|
for i:=0 to 31 do
|
|
if reg='f'+inttostr(i) then
|
|
rs.f[i]:=v;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
if reg[1]='f' then
|
|
for i:=0 to 31 do
|
|
if reg='f'+inttostr(i) then
|
|
rs.f[i]:=v;
|
|
{$endif cpusparc}
|
|
{$endif cpu_known}
|
|
p:=strscan(p1,#10);
|
|
if assigned(p) then
|
|
begin
|
|
p1:=strscan(p,' ');
|
|
inc(p);
|
|
end
|
|
else
|
|
break;
|
|
end;
|
|
{ free allocated memory }
|
|
strdispose(po);
|
|
end
|
|
else
|
|
exit;
|
|
end;
|
|
{ do not open a messagebox for such errors }
|
|
Debugger^.got_error:=false;
|
|
GetFPURegs:=true;
|
|
{$endif}
|
|
end;
|
|
|
|
constructor TFPUView.Init(var Bounds: TRect);
|
|
|
|
begin
|
|
inherited init(Bounds);
|
|
GrowMode:=gfGrowHiX or GfGrowHiY;
|
|
InDraw:=false;
|
|
first:=true;
|
|
FillChar(OldReg,Sizeof(oldreg),#0);
|
|
FillChar(NewReg,Sizeof(newreg),#0);
|
|
GDBCount:=-1;
|
|
{$ifndef cpu_known}
|
|
UseInfoFloat:=true;
|
|
{$endif not cpu_known}
|
|
end;
|
|
|
|
procedure TFPUView.Draw;
|
|
|
|
var
|
|
rs : tfpuregs;
|
|
top : byte;
|
|
color :byte;
|
|
ok : boolean;
|
|
i : byte;
|
|
const
|
|
TypeStr : Array[0..3] of string[6] =
|
|
('Valid ','Zero ','Spec ','Empty ');
|
|
|
|
procedure SetColor(Const x,y : string);
|
|
begin
|
|
if x=y then
|
|
color:=7
|
|
else
|
|
color:=8;
|
|
end;
|
|
|
|
procedure SetIColor(Const x,y : cardinal);
|
|
begin
|
|
if x=y then
|
|
color:=7
|
|
else
|
|
color:=8;
|
|
end;
|
|
|
|
begin
|
|
inherited draw;
|
|
{$ifdef NODEBUG}
|
|
WriteStr(1,0,'<no values available>',7);
|
|
{$else NODEBUG}
|
|
If not assigned(Debugger) then
|
|
begin
|
|
WriteStr(1,0,'<no values available>',7);
|
|
exit;
|
|
end;
|
|
if InDraw then
|
|
exit;
|
|
InDraw:=true;
|
|
if GDBCount<>Debugger^.RunCount then
|
|
begin
|
|
OldReg:=NewReg;
|
|
OK:=GetFPURegs(rs
|
|
{$ifndef cpu_known}
|
|
,UseInfoFloat
|
|
{$endif not cpu_known}
|
|
);
|
|
NewReg:=rs;
|
|
{ get inital values }
|
|
if first then
|
|
begin
|
|
OldReg:=NewReg;
|
|
first:=false;
|
|
end;
|
|
GDBCount:=Debugger^.RunCount;
|
|
end
|
|
else
|
|
begin
|
|
rs:=newreg;
|
|
OK:=true;
|
|
end;
|
|
if OK then
|
|
begin
|
|
{$ifdef cpu_known}
|
|
{$ifdef cpui386}
|
|
top:=(rs.fstat shr 11) and 7;
|
|
SetColor(rs.st0,OldReg.st0);
|
|
WriteStr(1,0,'ST0 '+TypeStr[(rs.ftag shr (2*((0+top) and 7))) and 3]+rs.st0,color);
|
|
SetColor(rs.st1,OldReg.st1);
|
|
WriteStr(1,1,'ST1 '+TypeStr[(rs.ftag shr (2*((1+top) and 7))) and 3]+rs.st1,color);
|
|
SetColor(rs.st2,OldReg.st2);
|
|
WriteStr(1,2,'ST2 '+TypeStr[(rs.ftag shr (2*((2+top) and 7))) and 3]+rs.st2,color);
|
|
SetColor(rs.st3,OldReg.st3);
|
|
WriteStr(1,3,'ST3 '+TypeStr[(rs.ftag shr (2*((3+top) and 7))) and 3]+rs.st3,color);
|
|
SetColor(rs.st4,OldReg.st4);
|
|
WriteStr(1,4,'ST4 '+TypeStr[(rs.ftag shr (2*((4+top) and 7))) and 3]+rs.st4,color);
|
|
SetColor(rs.st5,OldReg.st5);
|
|
WriteStr(1,5,'ST5 '+TypeStr[(rs.ftag shr (2*((5+top) and 7))) and 3]+rs.st5,color);
|
|
SetColor(rs.st6,OldReg.st6);
|
|
WriteStr(1,6,'ST6 '+TypeStr[(rs.ftag shr (2*((6+top) and 7))) and 3]+rs.st6,color);
|
|
SetColor(rs.st7,OldReg.st7);
|
|
WriteStr(1,7,'ST7 '+TypeStr[(rs.ftag shr (2*((7+top) and 7))) and 3]+rs.st7,color);
|
|
SetIColor(rs.ftag,OldReg.ftag);
|
|
WriteStr(1,8,'FTAG '+hexstr(rs.ftag,4),color);
|
|
SetIColor(rs.fctrl,OldReg.fctrl);
|
|
WriteStr(13,8,'FCTRL '+hexstr(rs.fctrl,4),color);
|
|
SetIColor(rs.fstat,OldReg.fstat);
|
|
WriteStr(1,9,'FSTAT '+hexstr(rs.fstat,4),color);
|
|
SetIColor(rs.fop,OldReg.fop);
|
|
WriteStr(13,9,'FOP '+hexstr(rs.fop,4),color);
|
|
if (rs.fiseg<>OldReg.fiseg) or
|
|
(rs.fioff<>OldReg.fioff) then
|
|
color:=8
|
|
else
|
|
color:=7;
|
|
WriteStr(1,10,'FI '+hexstr(rs.fiseg,4)+':'+hexstr(rs.fioff,8),color);
|
|
if (rs.foseg<>OldReg.foseg) or
|
|
(rs.fooff<>OldReg.fooff) then
|
|
color:=8
|
|
else
|
|
color:=7;
|
|
WriteStr(1,11,'FO '+hexstr(rs.foseg,4)+':'+hexstr(rs.fooff,8),color);
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
SetColor(rs.fp0,OldReg.fp0);
|
|
WriteStr(1,0,'fp0 '+rs.fp0,color);
|
|
SetColor(rs.fp1,OldReg.fp1);
|
|
WriteStr(1,1,'fp1 '+rs.fp1,color);
|
|
SetColor(rs.fp2,OldReg.fp2);
|
|
WriteStr(1,2,'fp2 '+rs.fp2,color);
|
|
SetColor(rs.fp3,OldReg.fp3);
|
|
WriteStr(1,3,'fp3 '+rs.fp3,color);
|
|
SetColor(rs.fp4,OldReg.fp4);
|
|
WriteStr(1,4,'fp4 '+rs.fp4,color);
|
|
SetColor(rs.fp5,OldReg.fp5);
|
|
WriteStr(1,5,'fp5 '+rs.fp5,color);
|
|
SetColor(rs.fp6,OldReg.fp6);
|
|
WriteStr(1,6,'fp6 '+rs.fp6,color);
|
|
SetColor(rs.fp7,OldReg.fp7);
|
|
WriteStr(1,7,'fp7 '+rs.fp7,color);
|
|
SetIColor(rs.fpcontrol,OldReg.fpcontrol);
|
|
WriteStr(1,8,'fpcontrol '+hexstr(rs.fpcontrol,8),color);
|
|
SetIColor(rs.fpstatus,OldReg.fpstatus);
|
|
WriteStr(1,9,'fpstatus '+hexstr(rs.fpstatus,8),color);
|
|
SetIColor(rs.fpiaddr,OldReg.fpiaddr);
|
|
WriteStr(1,10,'fpiaddr '+hexstr(rs.fpiaddr,8),color);
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
for i:=0 to 31 do
|
|
begin
|
|
SetColor(rs.f[i],OldReg.f[i]);
|
|
if i<10 then
|
|
WriteStr(1,i,'f'+IntToStr(i)+' '+rs.f[i],color)
|
|
else
|
|
WriteStr(1,i,'f'+IntToStr(i)+' '+rs.f[i],color);
|
|
end;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
for i:=0 to 31 do
|
|
begin
|
|
SetColor(rs.f[i],OldReg.f[i]);
|
|
if i<10 then
|
|
WriteStr(1,i,'f'+IntToStr(i)+' '+rs.f[i],color)
|
|
else
|
|
WriteStr(1,i,'f'+IntToStr(i)+' '+rs.f[i],color);
|
|
end;
|
|
{$endif cpusparc}
|
|
{$else not cpu_known}
|
|
for i:=0 to MaxRegs-1 do
|
|
begin
|
|
SetColor(rs.freg[i],OldReg.freg[i]);
|
|
WriteStr(1,i,rs.freg[i],color);
|
|
end;
|
|
{$endif cpu_known}
|
|
end
|
|
else
|
|
WriteStr(0,0,'<debugger error>',7);
|
|
InDraw:=false;
|
|
{$endif NODEBUG}
|
|
end;
|
|
|
|
destructor TFPUView.Done;
|
|
|
|
begin
|
|
inherited done;
|
|
end;
|
|
|
|
{****************************************************************************
|
|
TFPUWindow
|
|
****************************************************************************}
|
|
|
|
constructor TFPUWindow.Init;
|
|
|
|
var
|
|
R : TRect;
|
|
|
|
begin
|
|
Desktop^.GetExtent(R);
|
|
{$ifdef cpui386}
|
|
R.A.X:=R.B.X-44;
|
|
R.B.Y:=R.A.Y+14;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
R.A.X:=R.B.X-44;
|
|
R.B.Y:=R.A.Y+14;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
R.A.X:=R.B.X-44;
|
|
R.B.Y:=R.A.Y+33;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
R.A.X:=R.B.X-44;
|
|
R.B.Y:=R.A.Y+33;
|
|
{$endif cpusparc}
|
|
{$ifndef cpu_known}
|
|
R.A.X:=R.B.X-44;
|
|
R.B.Y:=R.A.Y+33;
|
|
{$endif cpu_known}
|
|
inherited Init(R,dialog_fpu, wnNoNumber);
|
|
Flags:=wfClose or wfMove or wfgrow;
|
|
Palette:=wpCyanWindow;
|
|
HelpCtx:=hcFPURegisters;
|
|
R.Assign(1,1,Size.X-2,Size.Y-2);
|
|
RV:=new(PFPUView,init(R));
|
|
Insert(RV);
|
|
If assigned(FPUWindow) then
|
|
dispose(FPUWindow,done);
|
|
FPUWindow:=@Self;
|
|
Update;
|
|
end;
|
|
|
|
constructor TFPUWindow.Load(var S: TStream);
|
|
|
|
begin
|
|
inherited load(S);
|
|
GetSubViewPtr(S,RV);
|
|
If assigned(FPUWindow) then
|
|
dispose(FPUWindow,done);
|
|
FPUWindow:=@Self;
|
|
end;
|
|
|
|
procedure TFPUWindow.Store(var S: TStream);
|
|
|
|
begin
|
|
inherited Store(s);
|
|
PutSubViewPtr(S,RV);
|
|
end;
|
|
|
|
procedure TFPUWindow.Update;
|
|
|
|
begin
|
|
ReDraw;
|
|
end;
|
|
|
|
destructor TFPUWindow.Done;
|
|
|
|
begin
|
|
FPUWindow:=nil;
|
|
inherited done;
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
TVectorView
|
|
****************************************************************************}
|
|
|
|
function GetVectorRegs(var rs : TVectorRegs
|
|
{$ifndef cpu_known}
|
|
; UseInfoVector : boolean
|
|
{$endif not cpu_known}
|
|
) : boolean;
|
|
|
|
var
|
|
p,po : pchar;
|
|
p1 : pchar;
|
|
{$ifndef NODEBUG}
|
|
reg,value : string;
|
|
buffer : array[0..255] of char;
|
|
v : string;
|
|
res : cardinal;
|
|
i : longint;
|
|
err : word;
|
|
{$endif}
|
|
|
|
begin
|
|
GetVectorRegs:=false;
|
|
{$ifndef NODEBUG}
|
|
{$ifndef cpu_known}
|
|
if UseInfoVector then
|
|
begin
|
|
Debugger^.Command('info vector');
|
|
if Debugger^.Error then
|
|
begin
|
|
UseInfoVector:=false;
|
|
Debugger^.Command('info all');
|
|
end;
|
|
end
|
|
else
|
|
{$endif not cpu_known}
|
|
Debugger^.Command('info vector');
|
|
if Debugger^.Error then
|
|
exit
|
|
else
|
|
begin
|
|
po:=StrNew(Debugger^.GetOutput);
|
|
p:=po;
|
|
{$ifndef cpu_known}
|
|
i:=0;
|
|
{$endif not cpu_known}
|
|
if assigned(p) then
|
|
begin
|
|
fillchar(rs,sizeof(rs),0);
|
|
p1:=strscan(p,' ');
|
|
while assigned(p1) do
|
|
begin
|
|
strlcopy(buffer,p,p1-p);
|
|
reg:=strpas(buffer);
|
|
{$ifndef cpu_known}
|
|
p1:=strscan(p,#10);
|
|
if assigned(p1) then
|
|
begin
|
|
strlcopy(buffer,p,p1-p);
|
|
rs.vreg[i]:=ExtractTabs(strpas(buffer),8);
|
|
if i<MaxRegs-1 then
|
|
inc(i);
|
|
end;
|
|
{$else cpu_known}
|
|
p:=p1;
|
|
while p^=' ' do
|
|
inc(p);
|
|
if p^='$' then
|
|
p1:=strscan(p,#9)
|
|
else
|
|
p1:=strscan(p,#10);
|
|
strlcopy(buffer,p,p1-p);
|
|
v:=strpas(buffer);
|
|
for i:=1 to length(v) do
|
|
if v[i]=#9 then
|
|
v[i]:=' ';
|
|
val(v,res,err);
|
|
{$ifdef cpui386}
|
|
if reg[1]='x' then
|
|
for i:=0 to 7 do
|
|
begin
|
|
if reg='xmm'+inttostr(i) then
|
|
rs.xmm[i]:=v
|
|
end
|
|
else if reg='mxcsr' then
|
|
rs.mxcsr:=v
|
|
else if reg[1]='m' then
|
|
for i:=0 to 7 do
|
|
begin
|
|
if reg='mm'+inttostr(i) then
|
|
rs.mmx[i]:=v;
|
|
end;
|
|
{$endif cpui386}
|
|
{$ifdef cpupowerpc}
|
|
{ !!!! fixme }
|
|
if reg[1]='v' then
|
|
for i:=0 to 31 do
|
|
if reg='v'+inttostr(i) then
|
|
rs.m[i]:=v;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
{$endif cpusparc}
|
|
{$endif cpu_known}
|
|
p:=strscan(p1,#10);
|
|
if assigned(p) then
|
|
begin
|
|
p1:=strscan(p,' ');
|
|
inc(p);
|
|
end
|
|
else
|
|
break;
|
|
end;
|
|
{ free allocated memory }
|
|
strdispose(po);
|
|
end
|
|
else
|
|
exit;
|
|
end;
|
|
{ do not open a messagebox for such errors }
|
|
Debugger^.got_error:=false;
|
|
GetVectorRegs:=true;
|
|
{$endif}
|
|
end;
|
|
|
|
constructor TVectorView.Init(var Bounds: TRect);
|
|
|
|
begin
|
|
inherited init(Bounds);
|
|
GrowMode:=gfGrowHiX or GfGrowHiY;
|
|
InDraw:=false;
|
|
first:=true;
|
|
FillChar(OldReg,Sizeof(oldreg),#0);
|
|
FillChar(NewReg,Sizeof(newreg),#0);
|
|
GDBCount:=-1;
|
|
{$ifndef cpu_known}
|
|
UseInfoVector:=true;
|
|
{$endif not cpu_known}
|
|
end;
|
|
|
|
procedure TVectorView.Draw;
|
|
|
|
var
|
|
rs : tVectorregs;
|
|
top : byte;
|
|
color :byte;
|
|
ok : boolean;
|
|
i : byte;
|
|
const
|
|
TypeStr : Array[0..3] of string[6] =
|
|
('Valid ','Zero ','Spec ','Empty ');
|
|
|
|
procedure SetColor(Const x,y : string);
|
|
begin
|
|
if x=y then
|
|
color:=7
|
|
else
|
|
color:=8;
|
|
end;
|
|
|
|
procedure SetIColor(Const x,y : cardinal);
|
|
begin
|
|
if x=y then
|
|
color:=7
|
|
else
|
|
color:=8;
|
|
end;
|
|
|
|
begin
|
|
inherited draw;
|
|
{$ifdef NODEBUG}
|
|
WriteStr(1,0,'<no values available>',7);
|
|
{$else NODEBUG}
|
|
If not assigned(Debugger) then
|
|
begin
|
|
WriteStr(1,0,'<no values available>',7);
|
|
exit;
|
|
end;
|
|
if InDraw then
|
|
exit;
|
|
InDraw:=true;
|
|
if GDBCount<>Debugger^.RunCount then
|
|
begin
|
|
OldReg:=NewReg;
|
|
OK:=GetVectorRegs(rs
|
|
{$ifndef cpu_known}
|
|
,UseInfoVector
|
|
{$endif not cpu_known}
|
|
);
|
|
NewReg:=rs;
|
|
{ get inital values }
|
|
if first then
|
|
begin
|
|
OldReg:=NewReg;
|
|
first:=false;
|
|
end;
|
|
GDBCount:=Debugger^.RunCount;
|
|
end
|
|
else
|
|
begin
|
|
rs:=newreg;
|
|
OK:=true;
|
|
end;
|
|
if OK then
|
|
begin
|
|
{$ifdef cpu_known}
|
|
{$ifdef cpui386}
|
|
for i:=0 to 7 do
|
|
begin
|
|
SetColor(rs.xmm[i],OldReg.xmm[i]);
|
|
WriteStr(1,i,'xmm'+IntToStr(i)+' '+rs.xmm[i],color);
|
|
end;
|
|
|
|
SetColor(rs.mxcsr,OldReg.mxcsr);
|
|
WriteStr(1,i,'mxcsr'+IntToStr(i)+' '+rs.mxcsr,color);
|
|
|
|
for i:=0 to 7 do
|
|
begin
|
|
SetColor(rs.mmx[i],OldReg.mmx[i]);
|
|
WriteStr(1,i+8,'mmx'+IntToStr(i)+' '+rs.mmx[i],color);
|
|
end;
|
|
{$endif cpui386}
|
|
{$ifdef cpupowerpc}
|
|
for i:=0 to 31 do
|
|
begin
|
|
SetColor(rs.m[i],OldReg.m[i]);
|
|
if i<10 then
|
|
WriteStr(1,i,'m'+IntToStr(i)+' '+rs.m[i],color)
|
|
else
|
|
WriteStr(1,i,'m'+IntToStr(i)+' '+rs.m[i],color);
|
|
end;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
{ no mm regs on the sparc }
|
|
{$endif cpusparc}
|
|
{$else not cpu_known}
|
|
for i:=0 to MaxRegs-1 do
|
|
begin
|
|
SetColor(rs.vreg[i],OldReg.vreg[i]);
|
|
WriteStr(1,i,rs.vreg[i],color);
|
|
end;
|
|
{$endif cpu_known}
|
|
end
|
|
else
|
|
WriteStr(0,0,'<debugger error>',7);
|
|
InDraw:=false;
|
|
{$endif NODEBUG}
|
|
end;
|
|
|
|
destructor TVectorView.Done;
|
|
|
|
begin
|
|
inherited done;
|
|
end;
|
|
|
|
{****************************************************************************
|
|
TVectorWindow
|
|
****************************************************************************}
|
|
|
|
constructor TVectorWindow.Init;
|
|
|
|
var
|
|
R : TRect;
|
|
|
|
begin
|
|
Desktop^.GetExtent(R);
|
|
{$ifdef cpui386}
|
|
R.A.X:=R.B.X-60;
|
|
R.B.Y:=R.A.Y+19;
|
|
{$endif cpui386}
|
|
{$ifdef cpum68k}
|
|
R.A.X:=R.B.X-60;
|
|
R.B.Y:=R.A.Y+14;
|
|
{$endif cpum68k}
|
|
{$ifdef cpupowerpc}
|
|
R.A.X:=R.B.X-60;
|
|
R.B.Y:=R.A.Y+33;
|
|
{$endif cpupowerpc}
|
|
{$ifdef cpusparc}
|
|
R.A.X:=R.B.X-60;
|
|
R.B.Y:=R.A.Y+33;
|
|
{$endif cpusparc}
|
|
{$ifndef cpu_known}
|
|
R.A.X:=R.B.X-60;
|
|
R.B.Y:=R.A.Y+33;
|
|
{$endif cpu_known}
|
|
inherited Init(R,dialog_Vector, wnNoNumber);
|
|
Flags:=wfClose or wfMove or wfgrow;
|
|
Palette:=wpCyanWindow;
|
|
HelpCtx:=hcVectorRegisters;
|
|
R.Assign(1,1,Size.X-2,Size.Y-2);
|
|
RV:=new(PVectorView,init(R));
|
|
Insert(RV);
|
|
If assigned(VectorWindow) then
|
|
dispose(VectorWindow,done);
|
|
VectorWindow:=@Self;
|
|
Update;
|
|
end;
|
|
|
|
constructor TVectorWindow.Load(var S: TStream);
|
|
|
|
begin
|
|
inherited load(S);
|
|
GetSubViewPtr(S,RV);
|
|
If assigned(VectorWindow) then
|
|
dispose(VectorWindow,done);
|
|
VectorWindow:=@Self;
|
|
end;
|
|
|
|
procedure TVectorWindow.Store(var S: TStream);
|
|
|
|
begin
|
|
inherited Store(s);
|
|
PutSubViewPtr(S,RV);
|
|
end;
|
|
|
|
procedure TVectorWindow.Update;
|
|
|
|
begin
|
|
ReDraw;
|
|
end;
|
|
|
|
destructor TVectorWindow.Done;
|
|
|
|
begin
|
|
VectorWindow:=nil;
|
|
inherited done;
|
|
end;
|
|
|
|
|
|
procedure InitRegistersWindow;
|
|
begin
|
|
if RegistersWindow=nil then
|
|
begin
|
|
new(RegistersWindow,init);
|
|
DeskTop^.Insert(RegistersWindow);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure DoneRegistersWindow;
|
|
begin
|
|
if assigned(RegistersWindow) then
|
|
begin
|
|
DeskTop^.Delete(RegistersWindow);
|
|
RegistersWindow:=nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure InitFPUWindow;
|
|
begin
|
|
if FPUWindow=nil then
|
|
begin
|
|
new(FPUWindow,init);
|
|
DeskTop^.Insert(FPUWindow);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure DoneFPUWindow;
|
|
begin
|
|
if assigned(FPUWindow) then
|
|
begin
|
|
DeskTop^.Delete(FPUWindow);
|
|
FPUWindow:=nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure InitVectorWindow;
|
|
begin
|
|
if VectorWindow=nil then
|
|
begin
|
|
new(VectorWindow,init);
|
|
DeskTop^.Insert(VectorWindow);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure DoneVectorWindow;
|
|
begin
|
|
if assigned(VectorWindow) then
|
|
begin
|
|
DeskTop^.Delete(VectorWindow);
|
|
VectorWindow:=nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure RegisterFPRegsViews;
|
|
begin
|
|
RegisterType(RRegistersWindow);
|
|
RegisterType(RRegistersView);
|
|
RegisterType(RFPUWindow);
|
|
RegisterType(RFPUView);
|
|
RegisterType(RVectorView);
|
|
end;
|
|
|
|
end.
|
|
{$endif NODEBUG}
|