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.