mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 14:51:35 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1642 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			1642 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 Windows}
 | |
|   Windows,
 | |
| {$endif Windows}
 | |
|   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,
 | |
|   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
 | |
|   );
 | |
| 
 | |
| {$ifdef useresstrings}
 | |
| resourcestring
 | |
| {$else}
 | |
| const
 | |
| {$endif}
 | |
|       dialog_registers = 'Register View';
 | |
|       dialog_fpu = 'FPU View';
 | |
|       dialog_vector = 'Vector Unit View';
 | |
| 
 | |
| {****************************************************************************
 | |
|                          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 Windows 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,8,'mxcsr'+IntToStr(i)+'  '+rs.mxcsr,color);
 | |
| 
 | |
|             for i:=0 to 7 do
 | |
|               begin
 | |
|                 SetColor(rs.mmx[i],OldReg.mmx[i]);
 | |
|                 WriteStr(1,i+9,'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+20;
 | |
| {$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}
 | 
