Files
bds.mr.jtg/src.jtag/svf/jtag.svfAstScan.pas
T
2026-01-08 19:12:06 +01:00

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.