439 lines
12 KiB
ObjectPascal
439 lines
12 KiB
ObjectPascal
unit jtag.svfAstScan;
|
|
|
|
interface
|
|
uses
|
|
System.SysUtils,
|
|
jtag.svfAstNode;
|
|
|
|
type
|
|
TsvfAstScan = class( TsvfAstNode)
|
|
|
|
private
|
|
fInst : AnsiString;
|
|
fLength : integer;
|
|
fBytes : integer;
|
|
fNibbles : integer; // memory size in 4 bit nibbles
|
|
|
|
fDataTDI : PByte;
|
|
fDataTDO : PByte;
|
|
fDataMASK : PByte;
|
|
fDataSMASK : PByte;
|
|
|
|
|
|
fLenTDI : integer;
|
|
fLenTDO : integer;
|
|
fLenMASK : integer;
|
|
fLenSMASK : integer;
|
|
|
|
fCursor : integer;
|
|
fCursorN : integer; // Cursor in 4 bit nibbles for data input
|
|
|
|
strict private
|
|
function GetDataTDI : pByteArray;
|
|
function GetDataTDO : pByteArray;
|
|
function GetDataMASK : pByteArray;
|
|
function GetDataSMASK : pByteArray;
|
|
|
|
public
|
|
function AsText: AnsiString; override;
|
|
|
|
public
|
|
constructor Create( Inst: AnsiString; Length: AnsiString);
|
|
destructor Destroy; override;
|
|
|
|
public
|
|
procedure AddTDI( Data: AnsiString);
|
|
procedure AddTDO( Data: AnsiString);
|
|
procedure AddMASK( Data: AnsiString);
|
|
procedure AddSMASK( Data: AnsiString);
|
|
|
|
procedure BeginData;
|
|
procedure EndData;
|
|
|
|
public
|
|
property Inst : AnsiString read fInst;
|
|
property Bits : integer read fLength;
|
|
property Bytes : integer read fBytes;
|
|
|
|
property DataTDI : PByteArray read GetDataTDI;
|
|
property DataTDO : PByteArray read GetDataTDO;
|
|
property DataMASK : PByteArray read GetDataMASK;
|
|
property DataSMASK: PByteArray read GetDataSMASK;
|
|
|
|
property LenTDI : integer read fLenTDI;
|
|
property LenTDO : integer read fLenTDO;
|
|
property LenMASK : integer read fLenMASK;
|
|
property LenSMASK : integer read fLenSMASK;
|
|
|
|
end;
|
|
|
|
implementation
|
|
uses
|
|
Winapi.Windows,
|
|
// Dialogs,
|
|
jtag.svfProgram;
|
|
|
|
{ TsvfAstScan }
|
|
|
|
function hex2bin( hex: AnsiChar): byte;
|
|
begin
|
|
case hex of
|
|
'0'..'9': result := ord(hex) -ord('0');
|
|
'a'..'f': result := ord(hex) -ord('a') +10;
|
|
'A'..'F': result := ord(hex) -ord('A') +10;
|
|
else result := 0;
|
|
end;
|
|
end;
|
|
|
|
function hex2rbin( hex: AnsiChar): byte;
|
|
begin
|
|
case hex of
|
|
'0': result := $0;
|
|
'1': result := $8;
|
|
'2': result := $4;
|
|
'3': result := $C;
|
|
'4': result := $2;
|
|
'5': result := $A;
|
|
'6': result := $6;
|
|
'7': result := $E;
|
|
'8': result := $1;
|
|
'9': result := $9;
|
|
|
|
'A','a': result := $5;
|
|
'B','b': result := $D;
|
|
'C','c': result := $3;
|
|
'D','d': result := $B;
|
|
'E','e': result := $7;
|
|
'F','f': result := $F;
|
|
else result := 0;
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Constructor
|
|
// ================================================================================================
|
|
constructor TsvfAstScan.Create(Inst: AnsiString; Length: AnsiString);
|
|
begin
|
|
fInst := Inst;
|
|
fLength := StrToIntDef( Length, 0);
|
|
fBytes := ((fLength +7) div 8);
|
|
fNibbles := ((fLength +3) div 4);
|
|
|
|
|
|
fDataTDI := nil;
|
|
fDataTDO := nil;
|
|
fDataMASK := nil;
|
|
fDataSMASK := nil;
|
|
end;
|
|
|
|
|
|
// ================================================================================================
|
|
// Destructor
|
|
// ================================================================================================
|
|
destructor TsvfAstScan.Destroy;
|
|
begin
|
|
if Assigned( fDataTDI) then FreeMem( fDataTDI);
|
|
if Assigned( fDataTDO) then FreeMem( fDataTDO);
|
|
if Assigned( fDataMASK) then FreeMem( fDataMASK);
|
|
if Assigned( fDataSMASK) then FreeMem( fDataSMASK);
|
|
|
|
inherited;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// BeginData
|
|
// ================================================================================================
|
|
procedure TsvfAstScan.BeginData;
|
|
begin
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// EndData
|
|
// ================================================================================================
|
|
procedure TsvfAstScan.EndData;
|
|
begin
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// GetDataTDI
|
|
// ================================================================================================
|
|
function TsvfAstScan.GetDataTDI: pByteArray;
|
|
begin
|
|
result := PByteArray( fDataTDI);
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// GetDataTDO
|
|
// ================================================================================================
|
|
function TsvfAstScan.GetDataTDO: pByteArray;
|
|
begin
|
|
result := PByteArray( fDataTDO);
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// GetDataMASK
|
|
// ================================================================================================
|
|
function TsvfAstScan.GetDataMASK: pByteArray;
|
|
begin
|
|
result := PByteArray( fDataMASK);
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// GetDataSMASK
|
|
// ================================================================================================
|
|
function TsvfAstScan.GetDataSMASK: pByteArray;
|
|
begin
|
|
result := PByteArray( fDataSMASK);
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// AddTDI
|
|
//
|
|
// Note: The TDI stream can have an arbitrary length.
|
|
// ================================================================================================
|
|
procedure TsvfAstScan.AddTDI( Data: AnsiString);
|
|
var
|
|
i : integer;
|
|
|
|
begin
|
|
i := 1;
|
|
|
|
if not Assigned( fDataTDI) then
|
|
begin
|
|
fLenTDI := 0;
|
|
fCursor := fBytes -1;
|
|
fCursorN := fNibbles -1;
|
|
fDataTDI := AllocMem( fBytes);
|
|
end;
|
|
|
|
while i <= Length(Data) do
|
|
begin
|
|
if fCursorN mod 2 <> 0
|
|
then DataTDI[fCursorN div 2] := hex2rbin(Data[i])
|
|
else DataTDI[fCursorN div 2] := (hex2rbin(Data[i]) shl 4) or DataTDI[fCursorN div 2];
|
|
|
|
DEC(fCursorN);
|
|
|
|
INC(fLenTDI);
|
|
INC(i);
|
|
|
|
// DataTDI[fCursor] := (hex2bin(Data[i]) shl 4) or hex2bin(Data[i+1]);;
|
|
|
|
// DEC(fCursor);
|
|
// INC(fLenTDI);
|
|
|
|
// INC(i, 2);
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// AddTDO
|
|
// ================================================================================================
|
|
procedure TsvfAstScan.AddTDO( Data: AnsiString);
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
i := 1;
|
|
|
|
if not Assigned( fDataTDO) then
|
|
begin
|
|
fLenTDO := 0;
|
|
fCursor := fBytes -1;
|
|
fCursorN := fNibbles -1;
|
|
fDataTDO := AllocMem( fBytes);
|
|
end;
|
|
|
|
while i <= Length(Data) do
|
|
begin
|
|
if fCursorN mod 2 <> 0
|
|
then DataTDO[fCursorN div 2] := hex2bin(Data[i]) shl 4
|
|
else DataTDO[fCursorN div 2] := hex2bin(Data[i]) or (byte(DataTDO[fCursorN div 2]));
|
|
|
|
DEC(fCursorN);
|
|
|
|
INC(fLenTDO);
|
|
INC(i);
|
|
|
|
// DataTDO[fCursor] := (hex2bin(Data[i]) shl 4) or hex2bin(Data[i+1]);;
|
|
//
|
|
// DEC(fCursor);
|
|
// INC(fLenTDO);
|
|
//
|
|
// INC(i);
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// AddSMASK
|
|
// ================================================================================================
|
|
procedure TsvfAstScan.AddSMASK( Data: AnsiString);
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
i := 1;
|
|
|
|
if not Assigned( fDataSMASK) then
|
|
begin
|
|
fLenSMASK := 0;
|
|
fCursor := fBytes-1;
|
|
fCursorN := fNibbles -1;
|
|
fDataSMASK := AllocMem( fBytes);
|
|
end;
|
|
|
|
while i <= Length(Data) do
|
|
begin
|
|
if fCursorN mod 2 <> 0
|
|
then DataSMASK[fCursorN div 2] := hex2rbin(Data[i])
|
|
else DataSMASK[fCursorN div 2] := (hex2rbin(Data[i]) shl 4) or DataSMASK[fCursorN div 2];
|
|
|
|
DEC(fCursorN);
|
|
|
|
INC(fLenSMASK);
|
|
INC(i);
|
|
|
|
// DataSMASK[fCursor] := (hex2bin(Data[i]) shl 4) or hex2bin(Data[i+1]);;
|
|
// DataTDI [fCursor] := DataTDI[fCursor] and DataSMASK[fCursor];
|
|
//
|
|
// DEC(fCursor);
|
|
// INC(fLenSMASK);
|
|
//
|
|
// INC(i, 2);
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// AddMASK
|
|
// ================================================================================================
|
|
procedure TsvfAstScan.AddMASK( Data: AnsiString);
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
i := 1;
|
|
|
|
if not Assigned( fDataMASK) then
|
|
begin
|
|
fLenMASK := 0;
|
|
fCursor := fBytes -1;
|
|
fCursorN := fNibbles -1;
|
|
fDataMASK := AllocMem( fBytes);
|
|
end;
|
|
|
|
while i <= Length(Data) do
|
|
begin
|
|
if fCursorN mod 2 <> 0
|
|
then DataMASK[fCursorN div 2] := hex2rbin(Data[i])
|
|
else DataMASK[fCursorN div 2] := (hex2rbin(Data[i]) shl 4) or DataMASK[fCursorN div 2];
|
|
|
|
DEC(fCursorN);
|
|
|
|
INC(fLenMASK);
|
|
INC(i);
|
|
|
|
// DataMASK[fCursor] := (hex2bin(Data[i]) shl 4) or hex2bin(Data[i+1]);;
|
|
//
|
|
// DEC(fCursor);
|
|
// INC(fLenMASK);
|
|
//
|
|
// INC(i, 2);
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// AsText
|
|
// ================================================================================================
|
|
function TsvfAstScan.AsText: AnsiString;
|
|
|
|
const
|
|
spc = ' ';
|
|
|
|
|
|
function DumpData( PrefixLength: integer;
|
|
DataName : AnsiString;
|
|
Data : PByte;
|
|
DataLength : integer): AnsiString;
|
|
var
|
|
i : integer;
|
|
cnt: integer;
|
|
ptr: PByte;
|
|
b : byte;
|
|
s : AnsiChar;
|
|
|
|
|
|
begin
|
|
cnt := 0;
|
|
ptr := Data;
|
|
result := Format( '%-7s(',[DataName]);
|
|
|
|
for i:= 0 to DataLength-1 do
|
|
begin
|
|
if i mod 2 = 0
|
|
then b := (ptr^ shr 4) and $0f
|
|
else b := (ptr^ shr 0) and $0f;
|
|
|
|
case b of
|
|
$0: s := '0'; $1: s := '1'; $2: s := '2'; $3: s := '3';
|
|
$4: s := '4'; $5: s := '5'; $6: s := '6'; $7: s := '7';
|
|
$8: s := '8'; $9: s := '9'; $a: s := 'A'; $b: s := 'B';
|
|
$c: s := 'C'; $d: s := 'D'; $e: s := 'E'; $f: s := 'F';
|
|
end;
|
|
|
|
result := result +s;
|
|
|
|
if cnt = 60 then
|
|
begin
|
|
result := result +#13#10+ Copy(spc,1,PrefixLength+8);
|
|
cnt := 0;
|
|
end;
|
|
|
|
INC(cnt);
|
|
|
|
if i mod 2 = 1 then
|
|
INC(ptr);
|
|
end;
|
|
|
|
result := result +')';
|
|
end;
|
|
|
|
|
|
var
|
|
s: AnsiString;
|
|
|
|
|
|
|
|
begin
|
|
if fLenTDI > 0
|
|
then result := Format('%3s %-8d',[fInst, fLength])
|
|
else result := Format('%3s %d', [fInst, fLength]);
|
|
|
|
if fLength > 0 then
|
|
begin
|
|
if fLenTDI > 0 then
|
|
result := result + DumpData( 12, 'TDI', fDataTDI, fLenTDI);
|
|
|
|
if fLenSMASK > 0 then
|
|
begin
|
|
result := result + #13#10+ Copy( spc, 1, 12);
|
|
result := result + DumpData( 12, 'SMASK', fDataSMASK, fLenSMASK);
|
|
end;
|
|
|
|
if fLenTDO > 0 then
|
|
begin
|
|
result := result + #13#10+ Copy( spc, 1, 12);
|
|
result := result + DumpData( 12, 'TDO', fDataTDO, fLenTDO);
|
|
end;
|
|
|
|
if fLenMASK > 0 then
|
|
begin
|
|
result := result + #13#10+ Copy( spc, 1, 12);
|
|
result := result + DumpData( 12, 'MASK', fDataMASK, fLenMASK);
|
|
end;
|
|
end;
|
|
|
|
result := result +';' +#13#10;
|
|
end;
|
|
|
|
end.
|