unit jtag.svf2; interface uses Classes, jtag.types; type TsvfReturnCode = ( SVF_OK = 0, SVF_InvalidFile = -1 ); TScan = ( SCAN_HIR, SCAN_HDR, SCAN_TIR, SCAN_TDR, SCAN_SIR, SCAN_SDR ); TsvfDataTypeBit = ( dtTDIData, // TDI data is present dtTDOData, // TDO data is present dtMASKData, // MASK data is present dtSMASKData // SMASK data us present ); TsvfDataType = set of TsvfDataTypeBit; TjtagSVF = class protected fStream : TStream; fLogLevel : integer; fBuffer : PAnsiChar; fBufferIdx : cardinal; fBufferSize : cardinal; fJTAG : IJTAG; fLog : IJTAGLOG; fDataHIR : TsvfDataType; fDataHDR : TsvfDataType; fDataTIR : TsvfDataType; fDataTDR : TsvfDataType; fDataSIR : TsvfDataType; fDataSDR : TsvfDataType; protected fHIRSize : word; fHDRSize : word; fTIRSize : word; fTDRSize : word; fSIRSize : word; fSDRSize : word; fHIR_TDIData : PByte; fHDR_TDIData : PByte; fTIR_TDIData : PByte; fTDR_TDIData : PByte; fSIR_TDIData : PByte; fSDR_TDIData : PByte; fHIR_TDOData : PByte; fHDR_TDOData : PByte; fTIR_TDOData : PByte; fTDR_TDOData : PByte; fSIR_TDOData : PByte; fSDR_TDOData : PByte; fHIR_MASKData : PByte; fHDR_MASKData : PByte; fTIR_MASKData : PByte; fTDR_MASKData : PByte; fSIR_MASKData : PByte; fSDR_MASKData : PByte; fHIR_SMASKData : PByte; fHDR_SMASKData : PByte; fTIR_SMASKData : PByte; fTDR_SMASKData : PByte; fSIR_SMASKData : PByte; fSDR_SMASKData : PByte; fRUN_State : TJTAGState; protected procedure svfMemManager( scan : TScan; bits : cardinal); private function svfPRG : TsvfReturnCode; function svfScan( scan : TScan): TsvfReturnCode; function svfData( buf : PBYTE; bits : cardinal): TsvfReturnCode; function svfENDxR : TsvfReturnCode; function svfFreq : TsvfReturnCode; function svfState : TsvfReturnCode; function svfRun : TsvfReturnCode; public function SVF( Stream: TStream): TsvfReturnCode; procedure AfterConstruction; override; procedure BeforeDestruction; override; public property LogLevel : integer read fLogLevel write fLogLevel; property JTAGLOG : IJTAGLOG read fLog write fLog; property JTAG : IJTAG read fJTAG write fJTAG; end; implementation uses SysUtils; { TjtagSVF } // ================================================================================================ // after construction // ================================================================================================ procedure TjtagSVF.AfterConstruction; begin fRUN_State := DRPAUSE end; // ================================================================================================ // before destruction // ================================================================================================ procedure TjtagSVF.BeforeDestruction; begin svfMemManager( SCAN_HIR, 0); svfMemManager( SCAN_HDR, 0); svfMemManager( SCAN_TIR, 0); svfMemManager( SCAN_TDR, 0); svfMemManager( SCAN_SIR, 0); svfMemManager( SCAN_SDR, 0); inherited; end; // ================================================================================================ // svf // ================================================================================================ function TjtagSVF.SVF(Stream: TStream): TsvfReturnCode; begin if Assigned(Stream) then begin fBufferIdx := 0; fBufferSize := Stream.Size; fBuffer := GetMemory( fBufferSize); Stream.Seek( 0,soFromBeginning); Stream.Read( fBuffer^, Stream.Size); svfPRG; FreeMemory(fBuffer); fBuffer := nil; fBufferIdx := 0 end; end; // ================================================================================================ // svfPRG // ================================================================================================ function TjtagSVF.svfPRG: TsvfReturnCode; var tmp: AnsiString; begin result := SVF_OK; while true do begin while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9,#13,#10]) do inc(fBufferIdx); if fBufferIdx = fBufferSize then exit; case fBuffer[fBufferIdx] of // ---------------------------------------------------- // comment // ---------------------------------------------------- '!': begin tmp := ''; while (fBufferIdx < fBufferSize) and not (fBuffer[fBufferIdx] in [#13,#10]) do begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; writeln(tmp); while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#13,#10]) do inc(fBufferIdx); end; '/': begin inc( fBufferIdx); if fBuffer[fBufferIdx] = '/' then begin tmp := '/'; while (fBufferIdx < fBufferSize) and not (fBuffer[fBufferIdx] in [#13,#10]) do begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; writeln(tmp); while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#13,#10]) do inc(fBufferIdx); end; end; // ---------------------------------------------------- // HIR/HDR // ---------------------------------------------------- 'H': if fBufferIdx < fBufferSize then begin case fBuffer[fBufferIdx+1] of 'I': result := svfScan( SCAN_HIR); 'D': result := svfScan( SCAN_HDR); else result := SVF_InvalidFile; end; end; // ---------------------------------------------------- // TIR/TDR // ---------------------------------------------------- // TODO 1 : Implement TRST (xilinx miatt) 'T': if fBufferIdx < fBufferSize then begin case fBuffer[fBufferIdx+1] of 'I': result := svfScan( SCAN_TIR); 'D': result := svfScan( SCAN_TDR); else result := SVF_InvalidFile; end; end; // ---------------------------------------------------- // SIR/SDR // ---------------------------------------------------- 'S': if fBufferIdx < fBufferSize then begin case fBuffer[fBufferIdx+1] of 'I': result := svfScan( SCAN_SIR); 'D': result := svfScan( SCAN_SDR); 'T': result := svfState; else result := SVF_InvalidFile; end; end; // ---------------------------------------------------- // ENDIR/ENDDR // ---------------------------------------------------- 'E': if fBufferIdx < fBufferSize then begin if (fBuffer[fBufferIdx+1] = 'N') and (fBuffer[fBufferIdx+2] = 'D') then begin case fBuffer[fBufferIdx+3] of 'I': result := svfENDxR; 'D': result := svfENDxR; else result := SVF_InvalidFile end; end; end; // ---------------------------------------------------- // FREQUENCY // ---------------------------------------------------- 'F': result := svfFreq; // ---------------------------------------------------- // RUNTEST // ---------------------------------------------------- 'R': result := svfRun; end; end; end; // ================================================================================================ // SCAN // ================================================================================================ function TjtagSVF.svfSCAN(scan: TScan): TsvfReturnCode; function reverse( data: PByte; length: integer): string; var i : integer; n : byte; begin result := ''; for i:=0 to length-1 do begin n := (data[i] shr 4) and $0f; case n of 0 : result := '0' + result; 1 : result := '8' + result; 2 : result := '4' + result; 3 : result := 'C' + result; 4 : result := '2' + result; 5 : result := 'A' + result; 6 : result := '6' + result; 7 : result := 'E' + result; 8 : result := '1' + result; 9 : result := '9' + result; $a : result := '5' + result; $b : result := 'D' + result; $c : result := '3' + result; $d : result := 'B' + result; $e : result := '7' + result; $f : result := 'F' + result; end; n := (data[i] shr 0) and $0f; case n of 0 : result := '0' + result; 1 : result := '8' + result; 2 : result := '4' + result; 3 : result := 'C' + result; 4 : result := '2' + result; 5 : result := 'A' + result; 6 : result := '6' + result; 7 : result := 'E' + result; 8 : result := '1' + result; 9 : result := '9' + result; $a : result := '5' + result; $b : result := 'D' + result; $c : result := '3' + result; $d : result := 'B' + result; $e : result := '7' + result; $f : result := 'F' + result; end; end; end; var bits : cardinal; bytes : cardinal; tmp : AnsiString; i : integer; s : string; sTDI : string; sTDO : string; begin result := SVF_InvalidFile; if (fBuffer[fBufferIdx+2] = 'R') and (fBuffer[fBufferIdx+3] in [#32,#9]) then begin INC(fBufferIdx,3); // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; // check for digit if not (fBuffer[fBufferIdx] in ['0'..'9']) then exit; // read size bits := 0; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do begin bits := bits * 10 + ord(fBuffer[fBufferIdx]) - ord('0'); INC(fBufferIdx); end; svfMemManager( scan, bits); // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; case scan of SCAN_HIR: Exclude( fDataHIR, dtTDOData); SCAN_HDR: Exclude( fDataHDR, dtTDOData); SCAN_TIR: Exclude( fDataTIR, dtTDOData); SCAN_TDR: Exclude( fDataTDR, dtTDOData); SCAN_SIR: Exclude( fDataSIR, dtTDOData); SCAN_SDR: Exclude( fDataSDR, dtTDOData); end; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['T','M','S']) do begin tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; case scan of SCAN_HIR: begin if tmp = 'TDI' then Include( fDataHIR, dtTDIData) else if tmp = 'TDO' then Include( fDataHIR, dtTDOData) else if tmp = 'MASK' then Include( fDataHIR, dtMASKData) else if tmp = 'SMASK' then Include( fDataHIR, dtSMASKData) else exit; if tmp = 'TDI' then result := svfData(fHIR_TDIData, bits) else if tmp = 'TDO' then result := svfData(fHIR_TDOData, bits) else if tmp = 'MASK' then result := svfData(fHIR_MASKData, bits) else if tmp = 'SMASK' then result := svfData(fHIR_SMASKData, bits) end; SCAN_HDR: begin if tmp = 'TDI' then Include( fDataHDR, dtTDIData) else if tmp = 'TDO' then Include( fDataHDR, dtTDOData) else if tmp = 'MASK' then Include( fDataHDR, dtMASKData) else if tmp = 'SMASK' then Include( fDataHDR, dtSMASKData) else exit; if tmp = 'TDI' then result := svfData(fHDR_TDIData, bits) else if tmp = 'TDO' then result := svfData(fHDR_TDOData, bits) else if tmp = 'MASK' then result := svfData(fHDR_MASKData, bits) else if tmp = 'SMASK' then result := svfData(fHDR_SMASKData, bits) end; SCAN_TIR: begin if tmp = 'TDI' then Include( fDataTIR, dtTDIData) else if tmp = 'TDO' then Include( fDataTIR, dtTDOData) else if tmp = 'MASK' then Include( fDataTIR, dtMASKData) else if tmp = 'SMASK' then Include( fDataTIR, dtSMASKData) else exit; if tmp = 'TDI' then result := svfData(fTIR_TDIData, bits) else if tmp = 'TDO' then result := svfData(fTIR_TDOData, bits) else if tmp = 'MASK' then result := svfData(fTIR_MASKData, bits) else if tmp = 'SMASK' then result := svfData(fTIR_SMASKData, bits) end; SCAN_TDR: begin if tmp = 'TDI' then Include( fDataTDR, dtTDIData) else if tmp = 'TDO' then Include( fDataTDR, dtTDOData) else if tmp = 'MASK' then Include( fDataTDR, dtMASKData) else if tmp = 'SMASK' then Include( fDataTDR, dtSMASKData) else exit; if tmp = 'TDI' then result := svfData(fTDR_TDIData, bits) else if tmp = 'TDO' then result := svfData(fTDR_TDOData, bits) else if tmp = 'MASK' then result := svfData(fTDR_MASKData, bits) else if tmp = 'SMASK' then result := svfData(fTDR_SMASKData, bits) end; SCAN_SIR: begin if tmp = 'TDI' then Include( fDataSIR, dtTDIData) else if tmp = 'TDO' then Include( fDataSIR, dtTDOData) else if tmp = 'MASK' then Include( fDataSIR, dtMASKData) else if tmp = 'SMASK' then Include( fDataSIR, dtSMASKData) else exit; if tmp = 'TDI' then result := svfData(fSIR_TDIData, bits) else if tmp = 'TDO' then result := svfData(fSIR_TDOData, bits) else if tmp = 'MASK' then result := svfData(fSIR_MASKData, bits) else if tmp = 'SMASK' then result := svfData(fSIR_SMASKData, bits) end; SCAN_SDR: begin if tmp = 'TDI' then Include( fDataSDR, dtTDIData) else if tmp = 'TDO' then Include( fDataSDR, dtTDOData) else if tmp = 'MASK' then Include( fDataSDR, dtMASKData) else if tmp = 'SMASK' then Include( fDataSDR, dtSMASKData) else exit; if tmp = 'TDI' then result := svfData(fSDR_TDIData, bits) else if tmp = 'TDO' then result := svfData(fSDR_TDOData, bits) else if tmp = 'MASK' then result := svfData(fSDR_MASKData, bits) else if tmp = 'SMASK' then result := svfData(fSDR_SMASKData, bits) else exit; end; end; end; if fBuffer[fBufferIdx] = ';' then begin INC(fBufferIdx); result := SVF_OK; end; if Assigned( fJTAG) then begin bytes := (bits + 7) div 8; case scan of SCAN_SIR: begin writeln( Format('SIR(s) : %s', [reverse(fSIR_TDIData,bytes)])); fJTAG.sir( fSIR_TDIData, bits); writeln( Format('SIR(r) : %s', [reverse(fSIR_TDIData,bytes)])); if dtTDOData in fDataSIR then begin writeln( Format('SIR(o) : %s', [reverse(fSIR_TDOData,bytes)])); if dtMASKData in fDataSIR then begin writeln( Format('SIR(m) : %s', [reverse(fSIR_MASKData,bytes)])); for i:=0 to bytes -1 do begin fSIR_TDIData[i] := fSIR_TDIData[i] and fSIR_MASKData[i]; fSIR_TDOData[i] := fSIR_TDOData[i] and fSIR_MASKData[i]; if fSIR_TDIData[i] <> fSIR_TDOData[i] then begin bits := 0; end; end; writeln( Format('SIR(mr): %s', [reverse(fSIR_TDIData,bytes)])); writeln( Format('SIR(mo): %s', [reverse(fSIR_TDOData,bytes)])); end; end; writeln; end; SCAN_SDR: begin writeln( Format('SDR(s) : %s', [reverse(fSDR_TDIData,bytes)])); fJTAG.sdr( fSDR_TDIData, bits); writeln( Format('SDR(r) : %s', [reverse(fSDR_TDIData,bytes)])); if dtTDOData in fDataSDR then begin writeln( Format('SDR(o) : %s', [reverse(fSDR_TDOData,bytes)])); if dtMASKData in fDataSDR then begin writeln( Format('SDR(m) : %s', [reverse(fSDR_MASKData,bytes)])); for i:=0 to bytes -1 do begin fSDR_TDIData[i] := fSDR_TDIData[i] and fSDR_MASKData[i]; fSDR_TDOData[i] := fSDR_TDOData[i] and fSDR_MASKData[i]; end; sTDI := reverse(fSDR_TDIData,bytes); sTDO := reverse(fSDR_TDOData,bytes); writeln( Format('SDR(mr): %s', [sTDI])); writeln( Format('SDR(mo): %s', [sTDO])); end; s := ''; for i:=1 to Length(sTDI) do if sTDI[i] <> sTDO[i] then s := s + '^' else s := s + ' '; if Trim(s) <> '' then writeln( Format(' %s', [s])); end; writeln; end; end; end; end; end; // ================================================================================================ // ENDIR/ENDDR // ================================================================================================ function TjtagSVF.svfENDxR: TsvfReturnCode; var state : AnsiChar; tmp : AnsiString; begin result := SVF_InvalidFile; state := '0'; tmp := ''; if (fBuffer[fBufferIdx+4] = 'R') and (fBuffer[fBufferIdx+5] in [#32,#9]) then begin INC(fBufferIdx,5); // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if not (fBuffer[fBufferIdx] in ['I','D','R']) then exit; // read state name while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; // check state name if tmp = 'IRPAUSE' then else if tmp = 'DRPAUSE' then else if tmp = 'RESET' then else if tmp = 'IDLE' then else exit; // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if fBuffer[fBufferIdx] = ';' then begin inc( fBufferIdx); result := SVF_OK end; end; end; // ================================================================================================ // FREQUENCY // ================================================================================================ function TjtagSVF.svfFreq: TsvfReturnCode; var tmp: AnsiString; begin result := SVF_InvalidFile; tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; if fBufferIdx = fBufferSize then exit; if tmp = 'FREQUENCY' then begin // just skip for now while (fBufferIdx < fBufferSize) and not (fBuffer[fBufferIdx] in [#13,#10]) do inc(fBufferIdx); end; end; // ================================================================================================ // RUNTEST // ================================================================================================ function TjtagSVF.svfRun: TsvfReturnCode; var tmp: AnsiString; tck : integer; int : integer; frc : integer; exp : integer; state : TJTAGState; save : cardinal; pulses: cardinal; burst : WORD; label pulse; begin result := SVF_InvalidFile; tmp := ''; tck := 0; pulses := 0; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; if fBufferIdx = fBufferSize then exit; if tmp = 'RUNTEST' then begin // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; // get optional state state := UNDEF; if fBuffer[fBufferIdx] in ['I','D','R'] then begin tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; if tmp = 'DRPAUSE' then state := DRPAUSE else if tmp = 'IRPAUSE' then state := IRPAUSE else if tmp = 'RESET' then state := RESET else if tmp = 'IDLE' then state := IDLE else exit; end; // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if (fBufferIdx = fBufferSize) or not (fBuffer[fBufferIdx] in ['0'..'9']) then exit; save := fBufferIdx; // remember position // get number of TCK pulses or integer part of mintime int := 0; frc := 0; exp := 0; tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do begin int := int * 10 + integer(fBuffer[fBufferIdx]) - ord('0'); tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; if fBufferIdx = fBufferSize then exit; // "run_count run_clk" case if fBuffer[fBufferIdx] <> '.' then begin // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; // read 'TCK' or 'SCK' if (fBuffer[fBufferIdx+0] in ['T','S']) and (fBuffer[fBufferIdx+1] = 'C') and (fBuffer[fBufferIdx+2] = 'K') then begin tck := int; int := 0; inc(fBufferIdx,3); // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if fBuffer[fBufferIdx] = ';' then begin result := SVF_OK; inc(fBufferIdx); goto pulse; end; end else exit; end else fBufferIdx := save; // read mintime int := 0; frc := 0; exp := 0; tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do begin int := int * 10 + integer(fBuffer[fBufferIdx]) - ord('0'); tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; if (fBufferIdx = fBufferSize) or (fBuffer[fBufferIdx] <> '.') then exit; tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); if (fBufferIdx = fBufferSize) or not (fBuffer[fBufferIdx] in ['0'..'9']) then exit; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do begin frc := frc + integer(fBuffer[fBufferIdx]) - ord('0'); tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; // match exponent letter: 'E' if (fBufferIdx = fBufferSize) or (fBuffer[fBufferIdx] <> 'E') then exit; tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); // match optional sign: ('+' | '-') if fBuffer[fBufferIdx] in ['-','+'] then begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; // match exponent: ('0'..'9')+ if (fBufferIdx = fBufferSize) or not (fBuffer[fBufferIdx] in ['0'..'9']) then exit; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do begin exp := exp + integer(fBuffer[fBufferIdx]) - ord('0'); tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; // skip WS: (' ' | '\t')* while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; pulses := Round(StrToFloat(tmp) / 1e-6); // match second mark: 'SEC' if (fBufferIdx = fBufferSize) or (fBuffer[fBufferIdx] <> 'S') then exit; tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['S','E','C']) do begin tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; if tmp <> 'SEC' then exit; // skip WS: (' ' | '\t')* while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; // TODO:maxtime, endstate.... // match instruction terminator: ';' if fBuffer[fBufferIdx] <> ';' then exit; inc(fBufferIdx); result := SVF_OK; // ------------------------------------------------------------ // execute command // ------------------------------------------------------------ pulse: if Assigned( fJTAG) then begin pulses := pulses + tck; while(pulses > 0) do begin if pulses > 50000 then begin burst := 50000; pulses := pulses - 50000 end else begin burst := pulses; pulses := 0 end; fJTAG.run(state,burst); end; end; end; end; // ================================================================================================ // STATE // ================================================================================================ function TjtagSVF.svfState : TsvfReturnCode; var tmp : AnsiString; state : TJTAGState; begin result := SVF_InvalidFile; state := UNDEF; tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; if fBufferIdx = fBufferSize then exit; if tmp = 'STATE' then begin while true do begin tmp := ''; // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); // read state name while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do begin tmp := tmp + fBuffer[fBufferIdx]; INC(fBufferIdx); end; // check state name if tmp = 'IRPAUSE' then state := IRPAUSE else if tmp = 'DRPAUSE' then state := DRPAUSE else if tmp = 'RESET' then state := RESET else if tmp = 'IDLE' then state := IDLE else exit; // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if Assigned(JTAG) then JTAG.state(state); if fBuffer[fBufferIdx] = ';' then begin inc( fBufferIdx); result := SVF_OK; break; end; end; end; end; // ================================================================================================ // svfData // ================================================================================================ function TjtagSVF.svfData(buf: PBYTE; bits: cardinal): TsvfReturnCode; var tmp : AnsiString; bytes : cardinal; count : cardinal; b : byte; i : integer; function Reverse( c: AnsiChar): BYTE; var b: BYTE; begin Result := 0; case c of '0'..'9': b := ord(c) - ord('0'); 'A'..'F': b := ord(c) - ord('A') + 10; 'a'..'f': b := ord(c) - ord('a') + 10; end; if b and $08 = $08 then Result := Result + $01; if b and $04 = $04 then Result := Result + $02; if b and $02 = $02 then Result := Result + $04; if b and $01 = $01 then Result := Result + $08; end; begin result := SVF_InvalidFile; bytes := (bits + 7) div 8; // skip whitespaces while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if fBuffer[fBufferIdx] <> '(' then exit; inc( fBufferIdx); while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if not (fBuffer[fBufferIdx] in ['0'..'9','A'..'F','a'..'f']) then exit; tmp := ''; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9','A'..'F','a'..'f',#32,#9,#13,#10]) do begin if fBuffer[fBufferIdx] in ['0'..'9','A'..'F','a'..'f'] then tmp := tmp + fBuffer[fBufferIdx]; inc(fBufferIdx); end; if length(tmp) < (bits + 3) div 4 then exit; bytes := 0; count := 0; for i:=length(tmp) downto 1 do begin b := Reverse(tmp[i]); if count mod 2 = 0 then buf[bytes] := b shl 4 else buf[bytes] := buf[bytes] + b; if count mod 2 = 1 then inc(bytes); inc(count); if count * 4 >= bits then break; end; if fBufferIdx = fBufferSize then exit; while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; if fBuffer[fBufferIdx] <> ')' then exit; inc( fBufferIdx); while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9,#13,#10]) do INC(fBufferIdx); if fBufferIdx = fBufferSize then exit; result := SVF_OK end; // ================================================================================================ // svfMemManager // ================================================================================================ procedure TjtagSVF.svfMemManager( scan: TScan; bits: cardinal); var bytes: cardinal; begin bytes := (bits + 7) div 8; case scan of SCAN_HIR: begin if (bits = 0) or (bits > fHIRSize) then begin if Assigned(fHIR_TDIData) then FreeMemory(fHIR_TDIData); if Assigned(fHIR_TDOData) then FreeMemory(fHIR_TDOData); if Assigned(fHIR_MASKData) then FreeMemory(fHIR_MASKData); if Assigned(fHIR_SMASKData) then FreeMemory(fHIR_SMASKData); if bits = 0 then begin fHIR_TDIData := nil; fHIR_TDOData := nil; fHIR_MASKData := nil; fHIR_SMASKData := nil end else begin fHIR_TDIData := GetMemory(bytes); fHIR_TDOData := GetMemory(bytes); fHIR_MASKData := GetMemory(bytes); fHIR_SMASKData := GetMemory(bytes) end end; if fHIRSize <> bits then begin fHIRSize := bits; fDataHIR := [] end end; SCAN_HDR: begin if (bits = 0) or (bits > fHDRSize) then begin if Assigned(fHDR_TDIData) then FreeMemory(fHDR_TDIData); if Assigned(fHDR_TDOData) then FreeMemory(fHDR_TDOData); if Assigned(fHDR_MASKData) then FreeMemory(fHDR_MASKData); if Assigned(fHDR_SMASKData) then FreeMemory(fHDR_SMASKData); if bits = 0 then begin fHDR_TDIData := nil; fHDR_TDOData := nil; fHDR_MASKData := nil; fHDR_SMASKData := nil end else begin fHDR_TDIData := GetMemory(bytes); fHDR_TDOData := GetMemory(bytes); fHDR_MASKData := GetMemory(bytes); fHDR_SMASKData := GetMemory(bytes) end end; if fHDRSize <> bits then begin fHDRSize := bits; fDataHDR := [] end end; SCAN_TIR: begin if (bits = 0) or (bits > fTIRSize) then begin if Assigned(fTIR_TDIData) then FreeMemory(fTIR_TDIData); if Assigned(fTIR_TDOData) then FreeMemory(fTIR_TDOData); if Assigned(fTIR_MASKData) then FreeMemory(fTIR_MASKData); if Assigned(fTIR_SMASKData) then FreeMemory(fTIR_SMASKData); if bits = 0 then begin fTIR_TDIData := nil; fTIR_TDOData := nil; fTIR_MASKData := nil; fTIR_SMASKData := nil end else begin fTIR_TDIData := GetMemory(bytes); fTIR_TDOData := GetMemory(bytes); fTIR_MASKData := GetMemory(bytes); fTIR_SMASKData := GetMemory(bytes) end end; if fTIRSize <> bits then begin fTIRSize := bits; fDataTIR := [] end end; SCAN_TDR: begin if (bits = 0) or (bits > fTDRSize) then begin if Assigned(fTDR_TDIData) then FreeMemory(fTDR_TDIData); if Assigned(fTDR_TDOData) then FreeMemory(fTDR_TDOData); if Assigned(fTDR_MASKData) then FreeMemory(fTDR_MASKData); if Assigned(fTDR_SMASKData) then FreeMemory(fTDR_SMASKData); if bits = 0 then begin fTDR_TDIData := nil; fTDR_TDOData := nil; fTDR_MASKData := nil; fTDR_SMASKData := nil end else begin fTDR_TDIData := GetMemory(bytes); fTDR_TDOData := GetMemory(bytes); fTDR_MASKData := GetMemory(bytes); fTDR_SMASKData := GetMemory(bytes) end end; if fTDRSize <> bits then begin fTDRSize := bits; fDataTDR := [] end end; SCAN_SIR: begin if (bits = 0) or (bits > fSIRSize) then begin if Assigned(fSIR_TDIData) then FreeMemory(fSIR_TDIData); if Assigned(fSIR_TDOData) then FreeMemory(fSIR_TDOData); if Assigned(fSIR_MASKData) then FreeMemory(fSIR_MASKData); if Assigned(fSIR_SMASKData) then FreeMemory(fSIR_SMASKData); if bits = 0 then begin fSIR_TDIData := nil; fSIR_TDOData := nil; fSIR_MASKData := nil; fSIR_SMASKData := nil end else begin fSIR_TDIData := GetMemory(bytes); fSIR_TDOData := GetMemory(bytes); fSIR_MASKData := GetMemory(bytes); fSIR_SMASKData := GetMemory(bytes) end end; if fSIRSize <> bits then begin fSIRSize := bits; fDataSIR := [] end end; SCAN_SDR: begin if (bits = 0) or (bits > fSDRSize) then begin if Assigned(fSDR_TDIData) then FreeMemory(fSDR_TDIData); if Assigned(fSDR_TDOData) then FreeMemory(fSDR_TDOData); if Assigned(fSDR_MASKData) then FreeMemory(fSDR_MASKData); if Assigned(fSDR_SMASKData) then FreeMemory(fSDR_SMASKData); if bits = 0 then begin fSDR_TDIData := nil; fSDR_TDOData := nil; fSDR_MASKData := nil; fSDR_SMASKData := nil end else begin fSDR_TDIData := GetMemory(bytes); fSDR_TDOData := GetMemory(bytes); fSDR_MASKData := GetMemory(bytes); fSDR_SMASKData := GetMemory(bytes) end end; if fSDRSize <> bits then begin fSDRSize := bits; fDataSDR := [] end end; end; end; end.