/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-5
**  FileName: VerifyPidSupportAndData.c
**  Author:   EnGenius
**  Date:     2/25/2022
**  Email:    <support@autosinnovate.org>
**
**  Purpose:  SAE J1699-5 Vehicle OBD II Compliance Test Cases Source Code.
**            This source code is intended to run the tests described in
**            the SAE J1699-5 document in an automated manner, when compiled
**            and used with an SAE J2534-compatible pass-thru device.
**
**            File j1699.c contains information on building and running this test.
**
**  Description:
**
**  Modifications:  03/13/2023  Initial Version
**
********************************************************************************
*******************************************************************************/

#include <stdio.h>    // C Library input and output declarations
#include <stdlib.h>   // C Library general function declarations
#include <string.h>   // C Library character array declarations
#include <time.h>     // C Library time and date declarations
#include <windows.h>  // Windows API declarations
#include "j2534.h"    // j1699 project j2534 declarations
#include "j1699.h"    // j1699 project general declarations


// Function Prototypes
extern BOOL SavePIDF501Data ( BYTE EcuIdx, BOOL bInitialSave );
STATUS DetermineVariablePIDSize ( void );
STATUS GetPid4FArray ( void );
STATUS GetPid50Array ( void );
void   GetHoursMinsSecs ( unsigned long time, unsigned long *pHours, unsigned long *pMins, unsigned long *pSecs );

void VerifyPidData   ( BYTE EcuIdx, PID *pPid );
void VerifyPid01Data ( BYTE EcuIdx, PID *pPid );
void DisplayPid01    ( BYTE EcuIdx, BOOL bCC );
void VerifyPid03Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid04Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid05Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid06Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid07Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid08Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid09Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid0AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid0BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid0CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid0DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid0EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid0FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid10Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid11Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid12Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid14__1BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid1CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid13_1D ( BYTE EcuIdx, PID *pPid );
void VerifyPid1EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid1FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid21Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid22Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid23Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid24__2BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid2CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid2DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid2EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid2FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid30Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid31Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid32Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid33Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid34__3BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid3C__3FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid41Data ( BYTE EcuIdx, PID *pPid, BOOL bEngineDontCare );
void VerifyPid42Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid43Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid44Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid45Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid46Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid47Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid48Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid49Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid4AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid4BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid4CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid4DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid4EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid4FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid50Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid51Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid52Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid53Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid54Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid55Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid56Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid57Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid58Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid59Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid5AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid5BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid5CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid5DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid5EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid5FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid61Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid62Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid63Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid64Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid65Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid66Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid67Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid68Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid69Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid6AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid6BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid6CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid6DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid6EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid6FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid70Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid71Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid72Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid73Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid74Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid75Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid76Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid77Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid78Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid79Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid7AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid7BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid7CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid7DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid7EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid7FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid81Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid82Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid83Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid84Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid85Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid86Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid87Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid88Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid89Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid8AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid8BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid8CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid8DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid8EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid8FData ( BYTE EcuIdx, PID *pPid );
void VerifyPid90Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid91Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid92Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid93Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid94Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid95Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid96Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid97Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid98Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid99Data ( BYTE EcuIdx, PID *pPid );
void VerifyPid9AData ( BYTE EcuIdx, PID *pPid );
void VerifyPid9BData ( BYTE EcuIdx, PID *pPid );
void VerifyPid9CData ( BYTE EcuIdx, PID *pPid );
void VerifyPid9DData ( BYTE EcuIdx, PID *pPid );
void VerifyPid9EData ( BYTE EcuIdx, PID *pPid );
void VerifyPid9FData ( BYTE EcuIdx, PID *pPid );
void VerifyPidA1Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA2Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA3Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA4Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA5Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA6Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA7Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA8Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidA9Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidAAData ( BYTE EcuIdx, PID *pPid );
void VerifyPidABData ( BYTE EcuIdx, PID *pPid );
void VerifyPidACData ( BYTE EcuIdx, PID *pPid );
void VerifyPidADData ( BYTE EcuIdx, PID *pPid );
void VerifyPidAEData ( BYTE EcuIdx, PID *pPid );
void VerifyPidAFData ( BYTE EcuIdx, PID *pPid );
void VerifyPidB0Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB1Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB2Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB3Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB4Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB5Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB6Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB7Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB8Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidB9Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidBAData ( BYTE EcuIdx, PID *pPid );
void VerifyPidBBData ( BYTE EcuIdx, PID *pPid );
void VerifyPidBCData ( BYTE EcuIdx, PID *pPid );
void VerifyPidBDData ( BYTE EcuIdx, PID *pPid );
void VerifyPidBEData ( BYTE EcuIdx, PID *pPid );
void VerifyPidBFData ( BYTE EcuIdx, PID *pPid );
void VerifyPidC1Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC2Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC3Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC4Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC5Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC6Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC7Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC8Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidC9Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidCAData ( BYTE EcuIdx, PID *pPid );
void VerifyPidCBData ( BYTE EcuIdx, PID *pPid );
void VerifyPidCCData ( BYTE EcuIdx, PID *pPid );
void VerifyPidCDData ( BYTE EcuIdx, PID *pPid );
void VerifyPidCEData ( BYTE EcuIdx, PID *pPid );
void VerifyPidCFData ( BYTE EcuIdx, PID *pPid );
void VerifyPidD0Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD1Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD2Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD3Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD4Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD5Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD6Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD7Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD8Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidD9Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidDAData ( BYTE EcuIdx, PID *pPid );
void VerifyPidDBData ( BYTE EcuIdx, PID *pPid );
void VerifyPidDCData ( BYTE EcuIdx, PID *pPid );
STATUS VerifyPidF501Data ( BYTE EcuIdx, PID *pPid );
void DisplayPIDF501    ( BYTE EcuIdx );
void VerifyPidF502Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidF503Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidF504Data ( BYTE EcuIdx, PID *pPid );
void VerifyPidF505Data ( BYTE EcuIdx, PID *pPid );


// Variables
#define MAX_PIDS        0x105


// PID $01 Bit defines - for tracking support when
// 'at least one ECU' must have these bits set
#define DATA_B_BIT_0 0x00010000
#define DATA_B_BIT_1 0x00020000
#define DATA_B_BIT_2 0x00040000
#define DATA_B_BIT_3 0x00080000
#define DATA_C_BIT_0 0x00000100
#define DATA_C_BIT_1 0x00000200
#define DATA_C_BIT_2 0x00000400
#define DATA_C_BIT_3 0x00000800
#define DATA_C_BIT_5 0x00002000
#define DATA_C_BIT_6 0x00004000
#define DATA_C_BIT_7 0x00008000


// PID $F501 Bit defines - for tracking support when
// 'at least one ECU' must have these bits set
#define MIS_SUP      0x00000001
#define FUEL_SUP     0x00000002
#define COOL_SUP     0x00000004
#define CAT_SUP      0x00000008
#define HCCAT_SUP    0x00000010
#define NCAT_SUP     0x00000020
#define EVAP_SUP     0x00000040
#define PF_SUP       0x00000080
#define EGS_SUP      0x00000100
#define CV_SUP       0x00000200
#define EGR_SUP      0x00000400
#define CSER_SUP     0x00000800

#define F501_1_MIS_SUP    0x01  // $F501 Byte B (1)
#define F501_1_FUEL_SUP   0x02  // $F501 Byte B (1)
#define F501_1_CCM_SUP    0x04  // $F501 Byte B (1)
#define F501_1_COOL_SUP   0x08  // $F501 Byte B (1)
#define F501_2_CAT_SUP    0x01  // $F501 Byte C (2) (G)
#define F501_2_HCCAT_SUP  0x02  // $F501 Byte C (2) (D)
#define F501_2_HCAT_SUP   0x04  // $F501 Byte C (2) (G)
#define F501_2_NCAT_SUP   0x08  // $F501 Byte C (2) (D)
#define F501_3_EVAP_SUP   0x01  // $F501 Byte D (3) (G)
#define F501_3_AIR_SUP    0x02  // $F501 Byte D (3) (G)
#define F501_3_BP_SUP     0x04  // $F501 Byte D (3) (D)
#define F501_3_PF_SUP     0x08  // $F501 Byte D (3)
#define F501_4_EGS_SUP    0x01  // $F501 Byte E (4)
#define F501_4_CV_SUP     0x02  // $F501 Byte E (4)
#define F501_4_EGR_SUP    0x04  // $F501 Byte E (4)
#define F501_4_VVT_SUP    0x08  // $F501 Byte E (4)
#define F501_5_DOR_SUP    0x01  // $F501 Byte F (5)
#define F501_5_CSER_SUP   0x02  // $F501 Byte F (5)
#define F501_5_NAC_SUP    0x04  // $F501 Byte F (5) (D)
#define F501_5_OTH_SUP    0x08  // $F501 Byte F (5)


/*******************************************************************************
**  OBD type definitions
*******************************************************************************/
// maximum number of OBD types for SID $22 PID $1C
#define MAX_OBD_TYPES            0x40
const char *szOBD_TYPE[MAX_OBD_TYPES] =
{
"UNKNOWN",                      // 0x00
"OBD II",                       // 0x01  California-only OBD II certified
"OBD",                          // 0x02  US Federal only OBD-certified
"OBD and OBDII",                // 0x03  US 50-state certified or non-California vehicles certified to California OBD II requirements
"OBD I",                        // 0x04  Certified to California OBD I requirements
"NO OBD",                       // 0x05  Not certified to any OBD requirements
"EOBD",                         // 0x06  Euro OBD
"EOBD and OBD II",              // 0x07  Euro OBD and California OBD-II
"EOBD and OBD",                 // 0x08  Euro OBD and US Federal OBD
"EOBD, OBD, and OBD II",        // 0x09  Euro OBD, US Federal OBD, and California OBD-II
"JOBD",                         // 0x0A  Japan OBD
"JOBD and OBD II",              // 0x0B  Japan OBD and California OBD-II
"JOBD and EOBD",                // 0x0C  Japan OBD and Euro OBD
"JOBD, EOBD, and OBD II",       // 0x0D  Japan OBD, Euro OBD and California OBD-II
"OBD, EOBD, and KOBD",          // 0x0E  OBD, Euro OBD and Korea OBD
"OBD, OBDII, EOBD, and KOBD",   // 0x0F  OBD, OBD II, Euro OBD and Korea OBD
"reserved",                     // 0x10  SAE/ISO reserved
"EMD",                          // 0x11  US Heavy-duty vehicles (>14,000) certified to EMD
"EMD+",                         // 0x12  US Heavy-duty engines (>14,000) certified to EMD+
"HD OBD-C",                     // 0x13  US Heavy-duty engines (>14,000) certified to HDOBD as an extrapolated/child rating
"HD OBD",                       // 0x14  US Heavy-duty engines (>14,000) certified to HDOBD as a full OBD/parent rating
"WWH OBD",                      // 0x15  World Wide Harmonized OBD
"reserved",                     // 0x16  SAE/ISO reserved
"HD EOBD-I",                    // 0x17  Heavy Duty Euro OBD Stage I without NOx control
"HD EOBD-I N",                  // 0x18  Heavy Duty Euro OBD Stage I with NOx control
"HD EOBD-II",                   // 0x19  Heavy Duty Euro OBD Stage II without NOx control
"HD EOBD-II N",                 // 0x1A  Heavy Duty Euro OBD Stage II with NOx control
"HD-ZEV",                       // 0x1B  Heavy Duty ZEV 
"OBDBr-1",                      // 0x1C  Brazil OBD Phase 1
"OBDBr-2 and 2+",               // 0x1D  Brazil OBD Phase 2 and Phase 2+
"KOBD",                         // 0x1E  Korean OBD
"IOBD I",                       // 0x1F  India OBD I Bharat Stage 4
"IOBD II",                      // 0x20  India OBD II Bharat Stage 4
"HD EOBD-VI",                   // 0x21  Heavy Duty Euro OBD Stage VI
"OBD, OBDII, and HD OBD",       // 0x22  OBD, OBD II and HD OBD
"OBDBr-3",                      // 0x23  Brazil OBD Phase 3
"MC EOBD-I",                    // 0x24  Motorcycle, Euro OBD-I
"MC EOBD-II",                   // 0x25  Motorcycle, Euro OBD-II
"MC COBD-I",                    // 0x26  Motorcycle, China OBD-I
"MC TOBD-I",                    // 0x27  Motorcycle, Taiwan OBD-I
"MC JOBD-I",                    // 0x28  Motorcycle, Japan OBD-I
"CN-OBD-6",                     // 0x29  China Nationwide Stage 6
"OBDBr-P7",                     // 0x2A  Brazil OBD Phase 7
"CN-HDOBD-VI",                  // 0x2B  China Heavy Duty VI
"IOBD-I-BS6",                   // 0x2C  India OBD I Bharat Stage 6
"IOBD-II-BS6",                  // 0x2D  India OBD II Bharat Stage 6
"IHDOBD-BSVI",                  // 0x2E  India HD OBD Bharat Stage VI
"OBDBr-P8",                     // 0x2F  Brazil OBD Phase 8
"HD-JOBD-II",                   // 0x30  Japan Heavy Duty OBD-II
"HD-KOBD-II",                   // 0x31  Korea Heavy Duty OBD-II
"CN-OROBD-IV",                  // 0x32  China Off-Road OBD
"CARB ACC-II",                  // 0x33  Light Duty ZEV CARB ACC-II
"MC JOBD-II",                   // 0x34  Motorcycle, Japan OBD-II
"MC CARB OBD",                  // 0x35  Motorcycle, California (CARB) OBD
"MC EPA OBD",                   // 0x36  Motorcycle, Federal (EPA) OBD
"MC CARB & EPA OBD",            // 0x37  Motorcycle, 50-State (CARB & EPA) OBD
"HD ZEV CARB ZEP",              // 0x38  Heavy Duty ZEV, CARB ZEP
"CARB ACC-II & EPA TIER 4",     // 0x39  Light Duty ZEV, CARB ACC2 and EPA Tier 4 (w/ GTR 22)
"EPA TIER4",                    // 0x3A  EPA Tier 4 (w/ GTR 22)
"EPA HD",                       // 0x39  EPA HD OBD
};


/************************
**  Fuel type definitions
************************/
#define MAX_FUELTYPE_LENGTH 10
const char *szFUEL_TYPE[] =
{
	"NONE",      // 00 Not Available
	"GAS",       // 01 Gasoline
	"METH",      // 02 Methanol
	"ETH",       // 03 Ethanol
	"DSL",       // 04 Diesel
	"LPG",       // 05 Liquefied Petroleum Gas
	"CNG",       // 06 Compressed Natural Gas
	"PROP",      // 07 Propane
	"ELEC",      // 08 Battery/Electric
	"BI_GAS",    // 09 Bi-fuel vehicle using gasoline
	"BI_METH",   // 0A Bi-fuel vehicle using methanol
	"BI_ETH",    // 0B Bi-fuel vehicle using ethanol
	"BI_LPG",    // 0C Bi-fuel vehicle using LPG
	"BI_CNG",    // 0D Bi-fuel vehicle using CNG
	"BI_PROP",   // 0E Bi-fuel vehicle using propane
	"BI_ELEC",   // 0F Bi-fuel vehicle using battery [Not to be used]
	"BI_MIX",    // 10 Bi-fuel vehicle using battery and combustion engine [Not to be used]
	"HYB_GAS",   // 11 Hybrid vehicle using gasoline engine [Not to be used]
	"HYB_ETH",   // 12 Hybrid vehicle using gasoline engine on ethanol [Not to be used]
	"HYB_DSL",   // 13 Hybrid vehicle using diesel engine [Not to be used]
	"HYB_ELEC",  // 14 Hybrid vehicle using battery [Not to be used]
	"HYB_MIX",   // 15 Hybrid vehicle using battery and combustion engine [Not to be used]
	"HYB_REG",   // 16 Hybrid vehicle in regeneration mode [Not to be used]
	"NOT_USED",  // 17 (Bi-fuel vehicle using diesel) or (Natural Gas) (as defined in J1979) [Not to be used]
	"BI_NG",     // 18 Bi-fuel vehicle using Natural Gas
	"BI_DSL",    // 19 Bi-fuel vehicle using diesel
	"NG",        // 1A Natural Gas (Compressed or Liquefied Natural Gas)
	"DSL_CNG",   // 1B Dual Fuel � Diesel and CNG
	"DSL_LNG",   // 1C Dual Fuel � Diesel and LNG
	"FC_H2",     // 1D Fuel cell utilizing hydrogen
	"HICE_HHO",  // 1E Hydrogen Internal Combustion Engine
	"KERO",      // 1F Kerosene
	"RESERVED"   // 20 -FF RESERVED
};


/************************
**  Gear definitions
************************/
const char *szGEAR[] =
{
	"NEUTRAL",      // 00 Neutral
	"GEAR 1",
	"GEAR 2",
	"GEAR 3",
	"GEAR 4",
	"GEAR 5",
	"GEAR 6",
	"GEAR 7",
	"GEAR 8",
	"GEAR 9",
	"GEAR 10",
	"GEAR 11",
	"GEAR 12",
	"GEAR 13",
	"GEAR 14",
	"GEAR 15"
};


/************************
**  Gear definitions
************************/
const char *szCON_STATUS[] =
{
	"RESERVED",      // 00 reserved
	"OPEN LOOP",
	"CLOSED LOOP",
	"FAULT"
};


/************************
**  Hybrid/EV Battery ESS Thermal Mode definitions
************************/
const char *szHEV_BATT_THERM_MODE[] =
{
	"SYSTEM OFF",      // 00 OFF
	"ACTIVE COOLING",
	"PASSIVE COOLING",
	"ACTIVE HEATING",
	"PASSIVE HEATING"
};


/************************
**  Particulate warning system inducement status
************************/
const char *szINDUC_L_STATUS[] =
{
	"INACTIVE",      // 00 OFF
	"ENABLED",
	"ACTIVE",
	"NOT SUPPORTED"
};


/************************
**  NCD/PCD Warning Lamp status
************************/
const char *SZNCD_PCD_WARNING_LAMP_STATUS[] =
{
	"OFF",      // 00 OFF
	"CONTINUOUS ON",
	"BLINK",
	"NOT UTILIZED"
};


BOOL           bEngineDontCare;
long           TempData_long;
float          TempData_float;
BYTE           BitIndex;
BOOL           bNoncontiguousSupport = FALSE;
BOOL           bSupportEnded         = FALSE;
BOOL           bPid13Supported = FALSE;      // set if the current ECU supports PID $F413
BOOL           bPid1DSupported = FALSE;      // set if the current ECU supports PID $F41D
BOOL           bPid4FSupported = FALSE;      // set if the current ECU supports PID $F44F
BOOL           bPid50Supported = FALSE;      // set if the current ECU supports PID $F450

// PID $01 is different as we must track support for specific bits.
// In this case, the ULONG will be structured so that DATA_A is the
// most significant byte and DATA_D is the least significant byte (i.e., AABBCCDD)
unsigned long IMBitSupportFlags = 0;        // holds the PID 01 IM bits supported by the vehicle

unsigned long  hours;
unsigned long  mins;
unsigned long  secs;
unsigned int   gVariablePIDSize = 0;
BYTE Pid4F[MAX_ECUS][4];
BYTE Pid50[MAX_ECUS][4];
//PID *PIDF501;    // capture the response from SID01 PIDF501 response.


/*******************************************************************************
**
**  Function:  VerifyPidSupportAndData
**
**  Purpose:   Verify PID diagnostic support and data
**
*******************************************************************************/
STATUS VerifyPIDSupportAndData ( BOOL bDontCare )
{
	REQ_MSG        stReqMsg;
	PID           *pPid;
	BYTE           EcuIdx;
	STATUS         eRetCode;

	unsigned long  InitialFailureCount = 0;
	unsigned long  TempFailureCount = 0;
	BOOL           bPid9FSuccess = FALSE;
	BOOL           bPIDSupported[MAX_PIDS+1];    // an array of PIDs (TRUE if PID is supported)
	BOOL           bReqPidNotSupported = FALSE;  // set if a required PID is not supported
	unsigned short IdIdx;


	InitialFailureCount = GetFailureCount ( );

	bEngineDontCare = bDontCare;
	
	// Read $F4xx PID support PIDs
	if ( RequestIDSupportData ( PIDREQUEST, FALSE ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems verifying PID $F4xx supported data." ) == 'N' )
		{
			return FAIL;
		}
	}

	// Read $F5xx PID support PIDs
	if ( RequestIDSupportData ( PF5REQUEST, FALSE ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems verifying PID $F5xx supported data." ) == 'N' )
		{
			return FAIL;
		}
	}

	// Verify ECU did not drop out
	if ( VerifyECUCommunication ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems verifying link active." ) == 'N' )
		{
			return FAIL;
		}
	}

	// Determine size of PIDs $F406, $F407, $F408, $F409
	if ( DetermineVariablePIDSize ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems determining the size of variable PIDs." ) == 'N' )
		{
			return FAIL;
		}
	}

	if ( GetPid4FArray ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems getting PID $F44F." ) == 'N' )
		{
			return FAIL;
		}
	}

	if ( GetPid50Array ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems getting PID $F450." ) == 'N' )
		{
			return FAIL;
		}
	}


	if ( gbPhysicalAddressing == FALSE )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Request PID (SID $22 DID $F4xx) Functionally Addressed\n" );
	}
	else
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Request PID (SID $22 DID $F4xx) Physically Addressed\n" );
	}


	// For each PID
	for ( IdIdx = 0xF401;
	      IdIdx <= (0XF400 + MAX_PIDS);
	      IdIdx++ )
	{
		// clear PID supported indicator
		bPIDSupported[IdIdx-0xF400] = FALSE;

		// skip PID supported PIDs
		// and unsupported PIDs
		if ( IdIdx == 0xF420 || IdIdx == 0xF440 ||
		     IdIdx == 0xF460 || IdIdx == 0xF480 ||
		     IdIdx == 0xF4A0 || IdIdx == 0xF4C0 ||
		     IdIdx == 0xF4E0 || IdIdx == 0xF500 ||
		     IdIdx == 0xF520 || IdIdx == 0xF540 ||
		     IdIdx == 0xF560 || IdIdx == 0xF580 ||
		     IdIdx == 0xF5A0 || IdIdx == 0xF5C0 ||
		     IdIdx == 0xF5E0 ||
		     (IdIdx < 0xF500 && IsIDSupported ( ALLECUS, PIDREQUEST, IdIdx ) == FALSE) ||
		     (IdIdx > 0xF500 && IsIDSupported ( ALLECUS, PF5REQUEST, IdIdx ) == FALSE) )
		{
			continue;  // just go to the next itteration of the PID for loop
		}

		// save indication that PID is supported
		bPIDSupported[IdIdx-0xF400] = TRUE;

		stReqMsg.SID      = 0x22;
		stReqMsg.NumIds   = 1;
		stReqMsg.u.DID[0] = IdIdx;
		eRetCode = PASS;
		if ( gbPhysicalAddressing == FALSE && RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) != PASS )
		{
			eRetCode = FAIL;
		}
		else if ( gbPhysicalAddressing == TRUE )
		{
			gbAllECUResetCompleted = FALSE;
			for ( EcuIdx = 0;
			      EcuIdx < gNumOfECUs;
			      EcuIdx++ )
			{
				if ( (IdIdx < 0xF500 && IsIDSupported ( EcuIdx, PIDREQUEST, IdIdx)) ||
				     (IdIdx > 0xF500 && IsIDSupported ( EcuIdx, PF5REQUEST, IdIdx )) )
				{
					if ( RequestSID_PhysicallyAddressed_Single ( &stReqMsg, REQ_MSG_NORMAL, gstResponse[EcuIdx].ReqId ) != PASS )
					{
						eRetCode = FAIL;
					}
				}
			}
		}

		if ( eRetCode != PASS )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $%04X request\n",
			      IdIdx );
		}

		// check each ECU for data in it's reaponse
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( gstResponse[EcuIdx].PIDSize != 0 ||
			     (gstResponse[EcuIdx].bNAKReceived &&
			      gstResponse[EcuIdx].NAKCode == NAK_ID_NOT_SUPPORTED) )
			{
				break;  // leave ECU for loop
			}
		}

		// if none of the ECUs have any data for this PID, go to the next one
		if ( EcuIdx >= gNumOfECUs )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "No PID $%04X data\n",
			      IdIdx );
			continue;  // just go to the next itteration of the PID for loop
		}

		// get Failure Count to allow for FAILURE checks from this point on
		TempFailureCount = GetFailureCount ( );

		// Verify that all SID $22 PID data is valid
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			// Set ECU dependent PID flags
			bPid13Supported = IsIDSupported ( EcuIdx, PIDREQUEST, 0xF413 );
			bPid1DSupported = IsIDSupported ( EcuIdx, PIDREQUEST, 0xF41D );
			bPid4FSupported = IsIDSupported ( EcuIdx, PIDREQUEST, 0xF44F );
			bPid50Supported = IsIDSupported ( EcuIdx, PIDREQUEST, 0xF450 );

			// If PID is supported, check it
			if ( (IdIdx < 0xF500 && IsIDSupported ( EcuIdx, PIDREQUEST, IdIdx )) ||
			     (IdIdx > 0xF500 && IsIDSupported ( EcuIdx, PF5REQUEST, IdIdx )) )
			{
				pPid = (PID *)&gstResponse[EcuIdx].PID[0];

				// if received a nak
				if ( gstResponse[EcuIdx].bNAKReceived )
				{
					// nak $31 (ID not supported)
					if ( gstResponse[EcuIdx].NAKCode == NAK_ID_NOT_SUPPORTED )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  PID $%04X supported but received NAK $31 (Unsupported DID request)\n",
						      GetEcuId ( EcuIdx ),
						      IdIdx );
					}
					// other nak codes handles in RequestSID.Process___Msg
				}

				if ( gstResponse[EcuIdx].PIDSize == 0 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  PID $%04X supported but no data\n",
					      GetEcuId ( EcuIdx ),
					      IdIdx );
				}

				else if ( gstResponse[EcuIdx].bResponseReceived != TRUE )
				{
					continue;
				}

				else
				{
					VerifyPidData ( EcuIdx, pPid );
				}  // end else ... datasize != 0

			}  // end if (IsIDSupported (EcuIdx, IdIdx) == TRUE)
			// otherwise PID is not supported
			else
			{
				// if received a nak
				if ( gstResponse[EcuIdx].bNAKReceived )
				{
					// nak $31 (ID not supported)
					if ( gstResponse[EcuIdx].NAKCode == NAK_ID_NOT_SUPPORTED )
					{
						// Only 01, 02 and 41 are allowed to NAK $31
						// when not supported for functional addressing
						if ( gbPhysicalAddressing != TRUE &&
						     IdIdx != 0xF401 &&
						     IdIdx != 0xF402 &&
						     IdIdx != 0xF441 )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							     "ECU %X  SID $22 NAK $31 for functionally addressed request of unsupported PID!\n",
							      GetEcuId ( EcuIdx ) );
						}
					}
					// nak other than $31 is not allowed
					else
					{
						// all non-supported physically addressed requests
						// are required to NAK $31 when not supported
						if ( gbPhysicalAddressing == TRUE  )

						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							     "ECU %X  SID $22 NAK other than $31 was received for request of unsupported PID!\n",
							      GetEcuId ( EcuIdx ) );
						}
					}
				}
				// otherwise a nak was not received
				else
				{
				}
			}

		}  // end for (EcuIdx

	}  // end for (IdIdx



	if ( bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		/**************************************************************************
		* "Either Or" required PIDs
		**************************************************************************/
		// All non-ZEV vehicles require PID $F405 or $F467
		if ( gstUserInput.eEnergyType != ZEV &&
		     bPIDSupported[0x05] == FALSE &&
		     bPIDSupported[0x67] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F405 nor $F467 supported (Support of one required for all vehicles)\n" );
		}

		// Gasoline vehicles require PID $F40B, $F410, $F466 or $F487
		if ( gstUserInput.eFuelType == GASOLINE &&
		     (bPIDSupported[0x0B] == FALSE &&
		      bPIDSupported[0x10] == FALSE &&
		      bPIDSupported[0x66] == FALSE &&
		      bPIDSupported[0x87] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $F40B, $F487, $F410 nor $F466 supported (Support of one required for gasoline vehicles)\n" );
		}

		// Gasoline vehicles require PID $F40F or $F468
		if ( gstUserInput.eFuelType == GASOLINE &&
		     (bPIDSupported[0x0F] == FALSE &&
		      bPIDSupported[0x68] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F40F nor $F468 supported (Support of one required for gasoline vehicles)\n" );
		}

		// Gasoline vehicles require PID $F413 or $F41D
		if ( gstUserInput.eFuelType == GASOLINE &&
		     (bPIDSupported[0x13] == FALSE &&
		      bPIDSupported[0x1D] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F413 nor $F41D supported (Support of one required for gasoline vehicles)\n" );
		}

		// all non-ZEV vehicles require PID $F421 or $F44D
		if ( gstUserInput.eEnergyType != ZEV &&
		     bPIDSupported[0x21] == FALSE &&
		     bPIDSupported[0x4D] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F421 nor PID $F44D supported (Support of one required for all vehicles)\n" );
		}

		// Diesel vehicles require PID $F42C or $F469
		if ( gstUserInput.eFuelType == DIESEL &&
		     (gstUserInput.eComplianceType == US_OBDII ||
		      gstUserInput.eComplianceType == HD_OBD   ||
		      gstUserInput.eComplianceType == CNOBD) &&
		     (bPIDSupported[0x2C] == FALSE &&
		      bPIDSupported[0x69] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F42C nor PID $F469 supported (Support of one required for diesel vehicles)\n", IdIdx );
		}

		// Diesel vehicles require PID $F42F or $F4C3
		if ( gstUserInput.eFuelType == DIESEL &&
		     bPIDSupported[0x2F] == FALSE &&
		     bPIDSupported[0xC3] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F42F nor PID $F4C3 upported (Support of one required for diesel vehicles)\n", IdIdx );
		}

		// All non-ZEV vehicles require PID $31 or $4E
		if ( gstUserInput.eEnergyType != ZEV &&
		     bPIDSupported[0x31] == FALSE &&
		     bPIDSupported[0x4E] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F431 nor PID $F44E supported (Support of one required for all vehicles)\n" );
		}

		// HD Gasoline vehicles require PID $3C or $CF
		if ( gstUserInput.eFuelType == GASOLINE &&
		     gstUserInput.eComplianceType == HD_OBD &&
		     bPIDSupported[0x3C] == FALSE  &&
		     bPIDSupported[0xCF] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F43C nor $F4CF supported (Support required for heavy duty gasoline vehicles)\n" );
		}

		// Gasoline vehicles require PID $45 or $6C
		if ( gstUserInput.eFuelType == GASOLINE &&
		     ( bPIDSupported[0x45] == FALSE &&
		       bPIDSupported[0x6C] == FALSE ) )
		{
			if ( gstUserInput.eComplianceType == US_OBDII ||
			     gstUserInput.eComplianceType == HD_OBD )
			{
				bReqPidNotSupported = TRUE;
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "Neither PID $F445 nor PID $F46C supported (Support of one required for gasoline vehicles)\n", IdIdx );
			}
			else
			{
				Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "Neither PID $F445 nor PID $F46C supported (Support of one required for gasoline vehicles)\n", IdIdx );
			}
		}

		// HD Diesel vehicles require PID $83, $A7 or $C9
		if ( gstUserInput.eFuelType == DIESEL &&
		     gstUserInput.eComplianceType == HD_OBD &&
		     bPIDSupported[0x83] == FALSE &&
		     bPIDSupported[0xA7] == FALSE &&
		     bPIDSupported[0xC9] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F483, $F4A7 nor PID $F4C9 supported (Support of one required for heavy duty diesel vehicles)\n", IdIdx );
		}

		// Diesel vehicles require PID $85 or $9B
		if ( gstUserInput.eFuelType == DIESEL &&
		     (gstUserInput.eComplianceType == US_OBDII ||
		      gstUserInput.eComplianceType == HD_OBD) &&
		     ( bPIDSupported[0x85] == FALSE &&
		       bPIDSupported[0x9B] == FALSE ) )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F485 nor PID $F49B supported (Support of one required for diesel vehicles)\n", IdIdx );
		}

		// Diesel vehicles require PID $A1 or $A8
		if ( gstUserInput.eFuelType == DIESEL &&
		     gstUserInput.eComplianceType == HD_OBD &&
		     bPIDSupported[0xA1] == FALSE &&
		     bPIDSupported[0xA8] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither PID $F4A1 nor PID $F4A8 supported (Support of one required for Diesel vehicles)\n", IdIdx );
		}


		/**************************************************************************
		* Individually required PIDs
		**************************************************************************/
		for ( IdIdx = 0xF401;
		      IdIdx <= (0xF400+MAX_PIDS);
		      IdIdx++ )
		{
			if ( bPIDSupported[IdIdx-0xF400] == FALSE )
			{
				switch ( IdIdx )
				{
					case 0xF404:
					case 0xF40C:
					case 0xF41C:
					case 0xF41F:
					case 0xF430:
					case 0xF433:
					case 0xF442:
					case 0xF501:
					case 0xF502:
					case 0xF504:
					{
						// Must be supported for all non-ZEV vehicles
						if ( gstUserInput.eEnergyType != ZEV )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all vehicles)\n",
							      IdIdx );
						}
						// Must be supported for all ZEV vehicles
						else if ( IdIdx == 0xF41C ||
						          IdIdx == 0xF41F )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF403:
					case 0xF411:
					{
						// Must be supported for gasoline vehicles
						if ( gstUserInput.eFuelType == GASOLINE )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF406:
					case 0xF407:
					{
						// Warn if not supported for gasoline vehicles
						if ( gstUserInput.eFuelType == GASOLINE &&
						     gstUserInput.eComplianceType != OBDBr_NO_IUMPR )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF40D:
					{
						// Must be supported for all light and medium duty vehicles and heavy duty gasoline vehicles (including ZEV)
						if ( gstUserInput.eVehicleType == LD ||
						     gstUserInput.eVehicleType == MD ||
						     gstUserInput.eVehicleType == MDDC ||
						     (gstUserInput.eVehicleType == HD && gstUserInput.eFuelType == GASOLINE) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all light and medium duty vehicles and heavy duty gasoline vehicles)\n",
							      IdIdx );
						}
						// Warn if not supported for medium or heavy duty vehicles
						else if ( gstUserInput.eVehicleType == HD && gstUserInput.eFuelType == DIESEL )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all heavy duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF40E:
					{
						// Must be supported for gasoline vehicles
						if ( gstUserInput.eFuelType == GASOLINE )
						{
							bReqPidNotSupported = TRUE;
							if ( gbHybrid == TRUE )
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $%04X not supported (Support required for gasoline vehicles)\n",
								      IdIdx );
							}
							else
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $%04X not supported (Support required for gasoline vehicles)\n",
								      IdIdx );
							}
						}
					}
					break;

					case 0xF42E:
					{
						// Warn if not supported for gasoline vehicles
						if ( gstUserInput.eFuelType == GASOLINE )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF42F:
					{
						// Warn if not supported for all non-ZEV vehicles
						if ( gstUserInput.eEnergyType != ZEV )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF431:
					case 0xF4B2:
					case 0xF4B9:
					case 0xF4D0:
					case 0xF4D1:
					case 0xF4D4:
					case 0xF4D6:
					case 0xF4DA:
					{
						// Fail if not supported for all ZEV vehicles
						if ( gstUserInput.eEnergyType == ZEV )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all ZEV vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF443:
					case 0xF444:
					{
						// Must be supported for gasoline vehicles
						if ( gstUserInput.eFuelType == GASOLINE )
						{
							if (gstUserInput.eComplianceType == US_OBDII ||
							    gstUserInput.eComplianceType == HD_OBD)
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $%04X not supported (Support required for gasoline vehicles)\n",
								      IdIdx );
							}
							else
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $%04X not supported (Support required for gasoline vehicles)\n",
								      IdIdx );
							}
						}
					}
					break;

					case 0xF446:
					case 0xF451:
					case 0xF462:
					{
						// Must be supported for all non-ZEV US vehicles
						if ( gstUserInput.eEnergyType != ZEV &&
						     (gstUserInput.eComplianceType == US_OBDII ||
						      gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all US vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF463:
					case 0xF48E:
					case 0xF49D:
					case 0xF49E:
					{
						// Must be supported for all US vehicles
						if ( (gstUserInput.eFuelType == DIESEL &&
						       gstUserInput.eComplianceType == HD_OBD) ||
						     gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for all US vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF449:
					{
						// Must be supported for diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for diesel vehicles)\n",
							      IdIdx );
						}
						// Must be supported for ZEV vehicles
						else if ( gstUserInput.eEnergyType == ZEV )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for ZEV vehicles)\n",
							      IdIdx );
						}

					}
					break;

					case 0xF45C:
					case 0xF45D:
					case 0xF45E:
					case 0xF465:
					{
						// Warn if not supported for US diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     (gstUserInput.eComplianceType == US_OBDII ||
						      gstUserInput.eComplianceType == HD_OBD) )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for US diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF45B:
					{
						// Must be supported for US hybrid and ZEV vehicles
						if ( gstUserInput.eEnergyType == ZEV ||
						     ((gstUserInput.ePwrTrnType == HEV ||
						       gstUserInput.ePwrTrnType == PHEV) &&
						      (gstUserInput.eComplianceType == US_OBDII ||
						       gstUserInput.eComplianceType == HD_OBD)) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for ZEV and US hybrid vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF461:
					case 0xF48B:
					{
						// Must be supported for US diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     (gstUserInput.eComplianceType == US_OBDII ||
						      gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for US diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF47D:
					case 0xF47E:
					case 0xF481:
					case 0xF488:
					{
						// Must be supported for US heavy and medium duty diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     (gstUserInput.eComplianceType == US_OBDII ||
						      gstUserInput.eComplianceType == HD_OBD) &&
						     (gstUserInput.eVehicleType == HD ||
						      gstUserInput.eVehicleType == MDDC) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for US heavy and medium duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF47F:
					{
						// Must be supported for heavy duty vehicles or medium duty diesel vehicles
						if ( gstUserInput.eComplianceType == HD_OBD ||
						     (gstUserInput.eFuelType == DIESEL &&
						      gstUserInput.eVehicleType == MDDC) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for heavy duty vehicles or medium duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF482:
					case 0xF489:
					case 0xF48A:
					{
						// Must be supported for medium and heavy duty diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     (gstUserInput.eVehicleType == HD   ||
						      gstUserInput.eVehicleType == MDDC ||
						      gstUserInput.eVehicleType == MD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for medium and heavy duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF49A:
					{
						// Must be supported for ZEV and US PHEV vehicles
						if ( gstUserInput.eEnergyType != ZEV &&
						     gbPlugIn == TRUE &&
						     gstUserInput.eComplianceType == US_OBDII )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for ZEV and US plug-in hybrid electric vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4A2:
					{
						// Must be supported for US diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     ((gstUserInput.eComplianceType == US_OBDII && gstUserInput.eVehicleType == MDDC) ||
						      gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for US diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4A5:
					{
						// Must be supported for US diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for MY 2019 and beyond OBD-II diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4A6:
					{
						// Must be supported for ZEV and US light and medium duty vehicles
						if ( gstUserInput.eEnergyType == ZEV ||
						     gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for ZEV and US medium and light duty vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4AA:
					{
						// Must be supported for US heavy duty vehicles
						if (  gstUserInput.eEnergyType != ZEV &&
						      gModelYear >= 2024 &&
						     gstUserInput.eComplianceType == HD_OBD )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for MY 2024 and beyond US heavy duty vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4AC:
					{
						// Must be supported for US heavy duty vehicles
						if ( gModelYear >= 2024 &&
						     gstUserInput.eFuelType == DIESEL &&
						     gstUserInput.eComplianceType == HD_OBD )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for MY 2024 and beyond US heavy duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4AE:
					{
						// Must be supported for US heavy duty gasoline vehicles
						if ( gstUserInput.eFuelType == GASOLINE &&
						     gstUserInput.eComplianceType == HD_OBD &&
						     gModelYear >= 2024 )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for US heavy duty gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4AF:
					{
						// Must be supported for US diesel vehicles
						if ( gstUserInput.eFuelType == DIESEL &&
						     gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for OBD-II diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4D3:
					{
						// Must be supported for HD OBD vehicles
						if ( gstUserInput.eComplianceType == HD_OBD )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for US heavy duty vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xF4D5:
					{
						// Must be supported for Hydrogen Fuel Cell vehicles
						if ( gstUserInput.ePowerType == FUELCELL )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "PID $%04X not supported (Support required for Hydrogen Fuel Cell (FCEV) vehicles)\n",
							      IdIdx );
						}
					}
					break;

				}  // end switch ( IdIdx )
			}  // end if ( bPIDSupported[IdIdx] == FALSE )
		
			// if bPIDSupported[IdIdx] == TRUE
			else
			{
				switch ( IdIdx )
				{
					// No UDS vehicles should support PID $F401, $F402, or $F441
					case 0xF401:
					case 0xF402:
					case 0xF441:
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "PID $%04X supported (Not allowed for any UDS vehicles).\n",
						      IdIdx );
					}
					break;


					case 0xF500:
					{
						if ( gModelYear > 2026 )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU $%X  PID $F4E0 Byte 3 Bit 0 is set ($F500 supported) (Not allowed for any UDS vehicles)\n",
							      GetEcuId ( EcuIdx ) );
						}
					}
					break;

					// if $F501 is supported, check the 'required by at least one ECU' bits
					case 0xF501:
					{
						if ( gstUserInput.eEnergyType != ZEV )
						{
							// Must be supported for all vehicles
							if ( (IMBitSupportFlags & MIS_SUP) != MIS_SUP )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $F501 DATA_B Bit 0 (MIS) not supported by at least one ECU (Support required for all vehicles)\n" );
							}
			
							if ( (IMBitSupportFlags & FUEL_SUP) != FUEL_SUP )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $F501 DATA_B Bit 1 (FUEL) not supported by at least one ECU (Support required for all vehicles)\n" );
							}
			
							if ( (IMBitSupportFlags & COOL_SUP) != COOL_SUP )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $F501 DATA_B Bit 3 (COOL) not supported by at least one ECU (Support required for all vehicles)\n" );
							}
			
							if ( (IMBitSupportFlags & EGS_SUP) != EGS_SUP )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $F501 DATA_E Bit 0 (EGS) not supported by at least one ECU (Support required for all vehicles)\n" );
							}
			
							if ( (IMBitSupportFlags & CV_SUP) != CV_SUP )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $F501 DATA_E Bit 1 (CV) not supported by at least one ECU (Support required for all vehicles)\n" );
							}
			
							if ( (IMBitSupportFlags & CSER_SUP) != CSER_SUP )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "PID $F501 DATA_F Bit 1 (CSER) not supported by at least one ECU (Support required for all vehicles)\n" );
							}
			
							// Must be supported for all Gasoline vehicles
							if ( gstUserInput.eFuelType == GASOLINE )
							{
								if ( (IMBitSupportFlags & CAT_SUP) != CAT_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_C Bit 0 (CAT) not supported by at least one ECU (Support required for all Gasoline vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & EVAP_SUP) != EVAP_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_D Bit 0 (EVAP) not supported by at least one ECU (Support required for all Gasoline vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & PF_SUP) != PF_SUP &&
								     gstUserInput.eComplianceType == CNOBD )
								{
									bReqPidNotSupported = TRUE;
									Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_D Bit 3 (PF) not supported by at least one ECU (Support required for all China6 Gasoline vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & CSER_SUP) != CSER_SUP &&
								     gstUserInput.eComplianceType == CNOBD )
								{
									bReqPidNotSupported = TRUE;
									Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_F Bit 0 (CSER_SUP) not supported by at least one ECU (Support required for all China6 Gasoline vehicles)\n" );
								}
							}  // end else if ( gstUserInput.eFuelType == GASOLINE )
	
							   // Must be supported for all Diesel vehicles
							else if ( gstUserInput.eFuelType == DIESEL )
							{
								if ( (IMBitSupportFlags & HCCAT_SUP) != HCCAT_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_C Bit 1 (HCCAT) not supported by at least one ECU (Support required for all Diesel vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & NCAT_SUP) != NCAT_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_C Bit 3 (NCAT) not supported by at least one ECU (Support required for all Diesel vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & PF_SUP) != PF_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_D Bit 3 (PF) not supported by at least one ECU (Support required for all Diesel vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & CSER_SUP) != CSER_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_F Bit 0 (CSER_SUP) not supported by at least one ECU (Support required for all Diesel vehicles)\n" );
								}
			
								if ( (IMBitSupportFlags & EGR_SUP) != EGR_SUP )
								{
									bReqPidNotSupported = TRUE;
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "PID $F501 DATA_E Bit 2 (EGR) not supported by at least one ECU (Support required for all Diesel vehicles)\n" );
								}
							}  // end else if ( gstUserInput.eFuelType == DIESEL )
						}  // end if ( gstUserInput.eEnergyType != ZEV )
					}  // end case 0xF501
					break;

					case 0xF600:
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU $%X  PID $F5E0 Byte 3 Bit 0 is set ($F600 supported) (Not allowed for any UDS vehicles)\n",
						      GetEcuId ( EcuIdx ) );
					}
					break;
				}  // end switch ( IdIdx )
			}  // end else (bPIDSupported[IdIdx] == TRUE)
		}  // end for ( IdIdx


		if ( bReqPidNotSupported == FALSE )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "All required PIDs supported!\n" );
		}
		else
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Not all required PIDs are supported\n" );
		}


		// Request group support
		if ( RequestGroupPIDSupportData ( PIDREQUEST ) == FAIL )
		{
			if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
				   "Problems verifying $F4xx group diagnostic support." ) == 'N' )
			{
				return FAIL;
			}
		}

		if ( RequestGroupPIDSupportData ( PF5REQUEST ) == FAIL )
		{
			if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
				   "Problems verifying $F5xx group diagnostic support." ) == 'N' )
			{
				return FAIL;
			}
		}

		// Link active test to verify communication remained active for ALL protocols
		if ( VerifyECUCommunication ( ) != PASS )
		{
			return FAIL;
		}
	} // end if ( bEngineDontCare == FALSE)

	if ( InitialFailureCount != GetFailureCount ( ) )
	{
		// There could have been early/late responses that weren't treated as FAIL
		// or PIDs out of range
		return FAIL;
	}

	return PASS;
}




/*******************************************************************************
**
**  Function:  VerifyPidData
**
**  Purpose:   Calls the PID data verification function for 
**
*******************************************************************************/
void VerifyPidData ( BYTE EcuIdx, PID *pPid )
{
	if ( pPid->PIDMSB == 0xF4 )
	{
		// Check various PID values for validity based on vehicle state
		switch ( pPid->PIDLSB )
		{
			case 0x01:
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  ECUs on a UDS vehicle should not respond to a PID $F401 requests.\n",
				      GetEcuId ( EcuIdx ) );
			}
			break;

			case 0x02:
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  ECUs on a UDS vehicle should not respond to a PID $F402 requests.\n",
				      GetEcuId ( EcuIdx ) );
			}
			break;

			case 0x03:
			{
				VerifyPid03Data ( EcuIdx, pPid );
			}
			break;

			case 0x04:
			{
				VerifyPid04Data ( EcuIdx, pPid );
			}
			break;

			case 0x05:
			{
				VerifyPid05Data ( EcuIdx, pPid );
			}
			break;

			case 0x06:
			{
				VerifyPid06Data ( EcuIdx, pPid );
			}
			break;

			case 0x07:
			{
				VerifyPid07Data ( EcuIdx, pPid );
			}
			break;

			case 0x08:
			{
				VerifyPid08Data ( EcuIdx, pPid );
			}
			break;

			case 0x09:
			{
				VerifyPid09Data ( EcuIdx, pPid );
			}
			break;

			case 0x0A:
			{
				VerifyPid0AData ( EcuIdx, pPid );
			}
			break;

			case 0x0B:
			{
				VerifyPid0BData ( EcuIdx, pPid );
			}
			break;

			case 0x0C:
			{
				VerifyPid0CData ( EcuIdx, pPid );
			}
			break;

			case 0x0D:
			{
				VerifyPid0DData ( EcuIdx, pPid );
			}
			break;

			case 0x0E:
			{
				VerifyPid0EData ( EcuIdx, pPid );
			}
			break;

			case 0x0F:
			{
				VerifyPid0FData ( EcuIdx, pPid );
			}
			break;

			case 0x10:
			{
				VerifyPid10Data ( EcuIdx, pPid );
			}
			break;

			case 0x11:
			{
				VerifyPid11Data ( EcuIdx, pPid );
			}
			break;

			case 0x12:
			{
				VerifyPid12Data ( EcuIdx, pPid );
			}
			break;

			/*
			case 0x13:  See 0x1D
			
			*/

			case 0x14:
			case 0x15:
			case 0x16:
			case 0x17:
			case 0x18:
			case 0x19:
			case 0x1A:
			case 0x1B:
			{
				VerifyPid14__1BData ( EcuIdx, pPid );
			}
			break;

			case 0x1C:
			{
				VerifyPid1CData ( EcuIdx, pPid );
			}
			break;

			case 0x13:
			case 0x1D:
			{
				VerifyPid13_1D ( EcuIdx, pPid );
			}
			break;

			case 0x1E:
			{
				VerifyPid1EData ( EcuIdx, pPid );
			}
			break;

			case 0x1F:
			{
				VerifyPid1FData ( EcuIdx, pPid );
			}
			break;

			case 0x21:
			{
				VerifyPid21Data ( EcuIdx, pPid );
			}
			break;

			case 0x22:
			{
				VerifyPid22Data ( EcuIdx, pPid );
			}
			break;

			case 0x23:
			{
				VerifyPid23Data ( EcuIdx, pPid );
			}
			break;

			case 0x24:
			case 0x25:
			case 0x26:
			case 0x27:
			case 0x28:
			case 0x29:
			case 0x2A:
			case 0x2B:
			{
				VerifyPid24__2BData ( EcuIdx, pPid );
			}
			break;

			case 0x2C:
			{
				VerifyPid2CData ( EcuIdx, pPid );
			}
			break;

			case 0x2D:
			{
				VerifyPid2DData ( EcuIdx, pPid );
			}
			break;

			case 0x2E:
			{
				VerifyPid2EData ( EcuIdx, pPid );
			}
			break;

			case 0x2F:
			{
				VerifyPid2FData ( EcuIdx, pPid );
			}
			break;

			case 0x30:
			{
				VerifyPid30Data ( EcuIdx, pPid );
			}
			break;

			case 0x31:
			{
				VerifyPid31Data ( EcuIdx, pPid );
			}
			break;

			case 0x32:
			{
				VerifyPid32Data ( EcuIdx, pPid );
			}
			break;

			case 0x33:
			{
				VerifyPid33Data ( EcuIdx, pPid );
			}
			break;

			case 0x34:
			case 0x35:
			case 0x36:
			case 0x37:
			case 0x38:
			case 0x39:
			case 0x3A:
			case 0x3B:
			{
				VerifyPid34__3BData ( EcuIdx, pPid );
			}
			break;

			case 0x3C:
			case 0x3D:
			case 0x3E:
			case 0x3F:
			{
				VerifyPid3C__3FData ( EcuIdx, pPid );
			}
			break;

			case 0x41:
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  ECUs on a UDS vehicle should not respond to a PID $F441 requests.\n",
				      GetEcuId ( EcuIdx ) );
			}
			break;

			case 0x42:
			{
				VerifyPid42Data ( EcuIdx, pPid );
			}
			break;

			case 0x43:
			{
				VerifyPid43Data ( EcuIdx, pPid );
			}
			break;

			case 0x44:
			{
				VerifyPid44Data ( EcuIdx, pPid );
			}
			break;

			case 0x45:
			{
				VerifyPid45Data ( EcuIdx, pPid );
			}
			break;

			case 0x46:
			{
				VerifyPid46Data ( EcuIdx, pPid );
			}
			break;

			case 0x47:
			{
				VerifyPid47Data ( EcuIdx, pPid );
			}
			break;

			case 0x48:
			{
				VerifyPid48Data ( EcuIdx, pPid );
			}
			break;

			case 0x49:
			{
				VerifyPid49Data ( EcuIdx, pPid );
			}
			break;

			case 0x4A:
			{
				VerifyPid4AData ( EcuIdx, pPid );
			}
			break;

			case 0x4B:
			{
				VerifyPid4BData ( EcuIdx, pPid );
			}
			break;

			case 0x4C:
			{
				VerifyPid4CData ( EcuIdx, pPid );
			}
			break;

			case 0x4D:
			{
				VerifyPid4DData ( EcuIdx, pPid );
			}
			break;

			case 0x4E:
			{
				VerifyPid4EData ( EcuIdx, pPid );
			}
			break;

			case 0x4F:
			{
				VerifyPid4FData ( EcuIdx, pPid );
			}
			break;

			case 0x50:
			{
				VerifyPid50Data ( EcuIdx, pPid );
			}
			break;

			case 0x51:
			{
				VerifyPid51Data ( EcuIdx, pPid );
			}
			break;

			case 0x52:
			{
				VerifyPid52Data ( EcuIdx, pPid );
			}
			break;

			case 0x53:
			{
				VerifyPid53Data ( EcuIdx, pPid );
			}
			break;

			case 0x54:
			{
				VerifyPid54Data ( EcuIdx, pPid );
			}
			break;

			case 0x55:
			{
				VerifyPid55Data ( EcuIdx, pPid );
			}
			break;

			case 0x56:
			{
				VerifyPid56Data ( EcuIdx, pPid );
			}
			break;

			case 0x57:
			{
				VerifyPid57Data ( EcuIdx, pPid );
			}
			break;

			case 0x58:
			{
				VerifyPid58Data ( EcuIdx, pPid );
			}
			break;

			case 0x59:
			{
				VerifyPid59Data ( EcuIdx, pPid );
			}
			break;

			case 0x5A:
			{
				VerifyPid5AData ( EcuIdx, pPid );
			}
			break;

			case 0x5B:
			{
				VerifyPid5BData ( EcuIdx, pPid );
			}
			break;

			case 0x5C:
			{
				VerifyPid5CData ( EcuIdx, pPid );
			}
			break;

			case 0x5D:
			{
				VerifyPid5DData ( EcuIdx, pPid );
			}
			break;

			case 0x5E:
			{
				VerifyPid5EData ( EcuIdx, pPid );
			}
			break;

			case 0x5F:
			{
				VerifyPid5FData ( EcuIdx, pPid );
			}
			break;

			case 0x61:
			{
				VerifyPid61Data ( EcuIdx, pPid );
			}
			break;

			case 0x62:
			{
				VerifyPid62Data ( EcuIdx, pPid );
			}
			break;

			case 0x63:
			{
				VerifyPid63Data ( EcuIdx, pPid );
			}
			break;

			case 0x64:
			{
				VerifyPid64Data ( EcuIdx, pPid );
			}
			break;

			case 0x65:
			{
				VerifyPid65Data ( EcuIdx, pPid );
			}
			break;

			case 0x66:
			{
				VerifyPid66Data ( EcuIdx, pPid );
			}
			break;

			case 0x67:
			{
				VerifyPid67Data ( EcuIdx, pPid );
			}
			break;

			case 0x68:
			{
				VerifyPid68Data ( EcuIdx, pPid );
			}
			break;

			case 0x69:
			{
				VerifyPid69Data ( EcuIdx, pPid );
			}
			break;

			case 0x6A:
			{
				VerifyPid6AData ( EcuIdx, pPid );
			}
			break;

			case 0x6B:
			{
				VerifyPid6BData ( EcuIdx, pPid );
			}
			break;

			case 0x6C:
			{
				VerifyPid6CData ( EcuIdx, pPid );
			}
			break;

			case 0x6D:
			{
				VerifyPid6DData ( EcuIdx, pPid );
			}
			break;

			case 0x6E:
			{
				VerifyPid6EData ( EcuIdx, pPid );
			}
			break;

			case 0x6F:
			{
				VerifyPid6FData ( EcuIdx, pPid );
			}
			break;

			case 0x70:
			{
				VerifyPid70Data ( EcuIdx, pPid );
			}
			break;

			case 0x71:
			{
				VerifyPid71Data ( EcuIdx, pPid );
			}
			break;

			case 0x72:
			{
				VerifyPid72Data ( EcuIdx, pPid );
			}
			break;

			case 0x73:
			{
				VerifyPid73Data ( EcuIdx, pPid );
			}
			break;

			case 0x74:
			{
				VerifyPid74Data ( EcuIdx, pPid );
			}
			break;

			case 0x75:
			{
				VerifyPid75Data ( EcuIdx, pPid );
			}
			break;

			case 0x76:
			{
				VerifyPid76Data ( EcuIdx, pPid );
			}
			break;

			case 0x77:
			{
				VerifyPid77Data ( EcuIdx, pPid );
			}
			break;

			case 0x78:
			{
				VerifyPid78Data ( EcuIdx, pPid );
			}
			break;

			case 0x79:
			{
				VerifyPid79Data ( EcuIdx, pPid );
			}
			break;

			case 0x7A:
			{
				VerifyPid7AData ( EcuIdx, pPid );
			}
			break;

			case 0x7B:
			{
				VerifyPid7BData ( EcuIdx, pPid );
			}
			break;

			case 0x7C:
			{
				VerifyPid7CData ( EcuIdx, pPid );
			}
			break;

			case 0x7D:
			{
				VerifyPid7DData ( EcuIdx, pPid );
			}
			break;

			case 0x7E:
			{
				VerifyPid7EData ( EcuIdx, pPid );
			}
			break;

			case 0x7F:
			{
				VerifyPid7FData ( EcuIdx, pPid );
			}
			break;

			case 0x81:
			{
				VerifyPid81Data ( EcuIdx, pPid );
			}
			break;

			case 0x82:
			{
				VerifyPid82Data ( EcuIdx, pPid );
			}
			break;

			case 0x83:
			{
				VerifyPid83Data ( EcuIdx, pPid );
			}
			break;

			case 0x84:
			{
				VerifyPid84Data ( EcuIdx, pPid );
			}
			break;

			case 0x85:
			{
				VerifyPid85Data ( EcuIdx, pPid );
			}
			break;

			case 0x86:
			{
				VerifyPid86Data ( EcuIdx, pPid );
			}
			break;

			case 0x87:
			{
				VerifyPid87Data ( EcuIdx, pPid );
			}
			break;

			case 0x88:
			{
				VerifyPid88Data ( EcuIdx, pPid );
			}
			break;

			case 0x89:
			{
				VerifyPid89Data ( EcuIdx, pPid );
			}
			break;

			case 0x8A:
			{
				VerifyPid8AData ( EcuIdx, pPid );
			}
			break;

			case 0x8B:
			{
				VerifyPid8BData ( EcuIdx, pPid );
			}
			break;

			case 0x8C:
			{
				VerifyPid8CData ( EcuIdx, pPid );
			}
			break;

			case 0x8D:
			{
				VerifyPid8DData ( EcuIdx, pPid );
			}
			break;

			case 0x8E:
			{
				VerifyPid8EData ( EcuIdx, pPid );
			}
			break;

			case 0x8F:
			{
				VerifyPid8FData ( EcuIdx, pPid );
			}
			break;

			case 0x90:
			{
				VerifyPid90Data ( EcuIdx, pPid );
			}
			break;

			case 0x91:
			{
				VerifyPid91Data ( EcuIdx, pPid );
			}
			break;

			case 0x92:
			{
				VerifyPid92Data ( EcuIdx, pPid );
			}
			break;

			case 0x93:
			{
				VerifyPid93Data ( EcuIdx, pPid );
			}
			break;

			case 0x94:
			{
				VerifyPid94Data ( EcuIdx, pPid );
			}
			break;

			case 0x95:
			{
				VerifyPid95Data ( EcuIdx, pPid );
			}
			break;

			case 0x96:
			{
				VerifyPid96Data ( EcuIdx, pPid );
			}
			break;

			case 0x97:
			{
				VerifyPid97Data ( EcuIdx, pPid );
			}
			break;

			case 0x98:
			{
				VerifyPid98Data ( EcuIdx, pPid );
			}
			break;

			case 0x99:
			{
				VerifyPid99Data ( EcuIdx, pPid );
			}
			break;

			case 0x9A:
			{
				VerifyPid9AData ( EcuIdx, pPid );
			}
			break;

			case 0x9B:
			{
				VerifyPid9BData ( EcuIdx, pPid );
			}
			break;

			case 0x9C:
			{
				VerifyPid9CData ( EcuIdx, pPid );
			}
			break;

			case 0x9D:
			{
				VerifyPid9DData ( EcuIdx, pPid );
			}
			break;

			case 0x9E:
			{
				VerifyPid9EData ( EcuIdx, pPid );
			}
			break;

			case 0x9F:
			{
				VerifyPid9FData ( EcuIdx, pPid );
			}
			break;

			case 0xA1:
			{
				VerifyPidA1Data ( EcuIdx, pPid );
			}
			break;

			case 0xA2:
			{
				VerifyPidA2Data ( EcuIdx, pPid );
			}
			break;

			case 0xA3:
			{
				VerifyPidA3Data ( EcuIdx, pPid );
			}
			break;

			case 0xA4:
			{
				VerifyPidA4Data ( EcuIdx, pPid );
			}
			break;

			case 0xA5:
			{
				VerifyPidA5Data ( EcuIdx, pPid );
			}
			break;

			case 0xA6:
			{
				VerifyPidA6Data ( EcuIdx, pPid );
			}
			break;

			case 0xA7:
			{
				VerifyPidA7Data ( EcuIdx, pPid );
			}
			break;

			case 0xA8:
			{
				VerifyPidA8Data ( EcuIdx, pPid );
			}
			break;

			case 0xA9:
			{
				VerifyPidA9Data ( EcuIdx, pPid );
			}
			break;

			case 0xAA:
			{
				VerifyPidAAData ( EcuIdx, pPid );
			}
			break;

			case 0xAB:
			{
				VerifyPidABData ( EcuIdx, pPid );
			}
			break;

			case 0xAC:
			{
				VerifyPidACData ( EcuIdx, pPid );
			}
			break;

			case 0xAD:
			{
				VerifyPidADData ( EcuIdx, pPid );
			}
			break;

			case 0xAE:
			{
				VerifyPidAEData ( EcuIdx, pPid );
			}
			break;

			case 0xAF:
			{
				VerifyPidAFData ( EcuIdx, pPid );
			}
			break;

			case 0xB0:
			{
				VerifyPidB0Data ( EcuIdx, pPid );
			}
			break;

			case 0xB1:
			{
				VerifyPidB1Data ( EcuIdx, pPid );
			}
			break;

			case 0xB2:
			{
				VerifyPidB2Data ( EcuIdx, pPid );
			}
			break;

			case 0xB3:
			{
				VerifyPidB3Data ( EcuIdx, pPid );
			}
			break;

			case 0xB4:
			{
				VerifyPidB4Data ( EcuIdx, pPid );
			}
			break;

			case 0xB5:
			{
				VerifyPidB5Data ( EcuIdx, pPid );
			}
			break;

			case 0xB6:
			{
				VerifyPidB6Data ( EcuIdx, pPid );
			}
			break;

			case 0xB7:
			{
				VerifyPidB7Data ( EcuIdx, pPid );
			}
			break;

			case 0xB8:
			{
				VerifyPidB8Data ( EcuIdx, pPid );
			}
			break;

			case 0xB9:
			{
				VerifyPidB9Data ( EcuIdx, pPid );
			}
			break;

			case 0xBA:
			{
				VerifyPidBAData ( EcuIdx, pPid );
			}
			break;

			case 0xBB:
			{
				VerifyPidBBData ( EcuIdx, pPid );
			}
			break;

			case 0xBC:
			{
				VerifyPidBCData ( EcuIdx, pPid );
			}
			break;

			case 0xBD:
			{
				VerifyPidBDData ( EcuIdx, pPid );
			}
			break;

			case 0xBE:
			{
				VerifyPidBEData ( EcuIdx, pPid );
			}
			break;

			case 0xBF:
			{
				VerifyPidBFData ( EcuIdx, pPid );
			}
			break;

			case 0xC1:
			{
				VerifyPidC1Data ( EcuIdx, pPid );
			}
			break;

			case 0xC2:
			{
				VerifyPidC2Data ( EcuIdx, pPid );
			}
			break;

			case 0xC3:
			{
				VerifyPidC3Data ( EcuIdx, pPid );
			}
			break;

			case 0xC4:
			{
				VerifyPidC4Data ( EcuIdx, pPid );
			}
			break;

			case 0xC5:
			{
				VerifyPidC5Data ( EcuIdx, pPid );
			}
			break;

			case 0xC6:
			{
				VerifyPidC6Data ( EcuIdx, pPid );
			}
			break;

			case 0xC7:
			{
				VerifyPidC7Data ( EcuIdx, pPid );
			}
			break;

			case 0xC8:
			{
				VerifyPidC8Data ( EcuIdx, pPid );
			}
			break;

			case 0xC9:
			{
				VerifyPidC9Data ( EcuIdx, pPid );
			}
			break;

			case 0xCA:
			{
				Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  PID $F4CA  is a RESERVED DID (DO NOT USE)\n",
				      GetEcuId ( EcuIdx ) );
//				VerifyPidCAData ( EcuIdx, pPid );
			}
			break;

			case 0xCB:
			{
				VerifyPidCBData ( EcuIdx, pPid );
			}
			break;

			case 0xCC:
			{
				VerifyPidCCData ( EcuIdx, pPid );
			}
			break;

			case 0xCD:
			{
				VerifyPidCDData ( EcuIdx, pPid );
			}
			break;

			case 0xCE:
			{
				VerifyPidCEData ( EcuIdx, pPid );
			}
			break;

			case 0xCF:
			{
				VerifyPidCFData ( EcuIdx, pPid );
			}
			break;

			case 0xD0:
			{
				VerifyPidD0Data ( EcuIdx, pPid );
			}
			break;

			case 0xD1:
			{
				VerifyPidD1Data ( EcuIdx, pPid );
			}
			break;

			case 0xD2:
			{
				VerifyPidD2Data ( EcuIdx, pPid );
			}
			break;

			case 0xD3:
			{
				VerifyPidD3Data ( EcuIdx, pPid );
			}
			break;

			case 0xD4:
			{
				VerifyPidD4Data ( EcuIdx, pPid );
			}
			break;

			case 0xD5:
			{
				VerifyPidD5Data ( EcuIdx, pPid );
			}
			break;

			case 0xD6:
			{
				VerifyPidD6Data ( EcuIdx, pPid );
			}
			break;

			case 0xD7:
			{
				VerifyPidD7Data ( EcuIdx, pPid );
			}
			break;

			case 0xD8:
			{
				VerifyPidD8Data ( EcuIdx, pPid );
			}
			break;

			case 0xD9:
			{
				VerifyPidD9Data ( EcuIdx, pPid );
			}
			break;

			case 0xDA:
			{
				VerifyPidDAData ( EcuIdx, pPid );
			}
			break;

			case 0xDB:
			{
				VerifyPidDBData ( EcuIdx, pPid );
			}
			break;

			case 0xDC:
			{
				VerifyPidDCData ( EcuIdx, pPid );
			}
			break;

			default:
			{
				// Non-OBD PID
			}
			break;

		}  // end switch ( pPid->PIDLSB )

	}  // end if PIDMSB == F4

	else if ( pPid->PIDMSB == 0xF5 )
	{
		// Check various PID values for validity based on vehicle state
		switch ( pPid->PIDLSB )
		{
			case 0x01:
			{
				VerifyPidF501Data ( EcuIdx, pPid );
			}
			break;

			case 0x02:
			{
				VerifyPidF502Data ( EcuIdx, pPid );
			}
			break;

			case 0x03:
			{
				VerifyPidF503Data ( EcuIdx, pPid );
			}
			break;

			case 0x04:
			{
				VerifyPidF504Data ( EcuIdx, pPid );
			}
			break;

			case 0x05:
			{
				VerifyPidF505Data ( EcuIdx, pPid );
			}
			break;
		}  // end switch $F5xx

	}  // end else if ( pPid->PIDMSB == 0XF5 )
}




/*******************************************************************************
**
**  Function:  VerifyPid01Data
**
**  Purpose:   Verify PID $F401 data, that all bits are in the approptiate state
**
*******************************************************************************/
void VerifyPid01Data ( BYTE EcuIdx, PID *pPid )
{
	DisplayPid01 ( EcuIdx, FALSE );

	// Check if the MIL light is ON (PID $F401 Data A Bit 7)
	if ( pPid->Data[0] & 0x80 )
	{
		if ( gbDTCStored == FALSE )
		{
			// MIL is ON when there should not be a stored DTC
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MIL status failure.\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Check if any DTC status bits (PID $F401 Data A Bits 0-6)
	if ( pPid->Data[0] & 0x7F )
	{
		// if DTC status bit(s) set when there should not be a stored DTC
		if ( gbDTCStored == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  DTC status failure.\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Evaluate Data B, BIT 0 - Misfire support
	if ( (pPid->Data[1] & 0x01) == 0x01 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_B_BIT_0;
	}

	// Evaluate Data B, BIT 1 - Fuel support
	if ( (pPid->Data[1] & 0x02) == 0x02 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_B_BIT_1;
	}

	// Evaluate Data B, BIT 2 - CCM support
	if ( (pPid->Data[1] & 0x04) != 0x04 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CCM monitor must be supported (CCM_SUP = 1 (YES))\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Check Data B BIT 3 state
	// Check if ECU does not only supports CCM requirements (PID $F401 Data B bit 2==1)
	if ( (gstResponse[EcuIdx].PIDF501.Data[1] & 0x03) != 0x00 ||
	     (gstResponse[EcuIdx].PIDF501.Data[2] & 0xFF) != 0x00 )
	{
		// Check for PID $01 Byte 1 Bit 3 to Gas/Deisel user input match
		if ( (pPid->Data[1] & 0x08) == 0x00 &&
		     gstUserInput.eFuelType == DIESEL  )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Data B bit 3 clear (Gasoline) does not match user input (Diesel)\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( (pPid->Data[1] & 0x08) == 0x08 &&
		          gstUserInput.eFuelType == GASOLINE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Data B bit 3 set (Diesel) does not match user input (Non Diesel)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Evaluate Data B, BIT 4 - Misfire status
	if ( (pPid->Data[1] & 0x01) == 0x01 )
	 {
		// if Misfire is supported
		if ( gstUserInput.eFuelType == GASOLINE )
		{
			// if it's a Gasoline engine
			if ( (pPid->Data[1] & 0x10) != 0x00 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  $F401  Misfire Monitor must be 0 (MIS_SUP = NO) for Gasoline vehicles or controllers that do not support misfire.\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		else
		{
			// Bit 4 may be 0 or 1 for Diesel w/ or wo/ Engine running
			// except in Test 11 where it must be complete (0).
			if ( geTestPhase == eTestPerformanceCounters )
			{
				if ( (pPid->Data[1] & 0x10) != 0x00 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  $F401  Misfire Monitor must be 0 (MIS_SUP = NO) for Diesel vehicles.\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}
	// If Misfire unsupported it must indicate complete
	if ( (pPid->Data[1] & 0x01) == 0x00 &&
	     (pPid->Data[1] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported Misfire Monitor (MIS_SUP = 0 (NO) ) must indicate complete (MIS_RDY = 0 (YES)).\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Evaluate Data B, BIT 5 - Fuel status
	if ( (pPid->Data[1] & 0x02 ) == 0x02 )
	{
		// only check for tests 11.3 and 11.7 (not 10.6)
		if ( geTestPhase == eTestPerformanceCounters &&
		     (pPid->Data[1] & 0x20) == 0x20 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported Fuel System Monitor (FUEL_SUP = 1 (YES)) must indicate complete (FUEL_RDY = 0 (YES)).\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	// If fuel system monitor unsupported it must indicate complete
	if ( (pPid->Data[1] & 0x02) == 0x00 &&
	     (pPid->Data[1] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported Fuel System Monitor (FUEL_SUP = 0 (NO)) must indicate complete (FUEL_RDY = 0 (YES)).\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Evaluate Data B, BIT 6 - CCM status
	if ( (pPid->Data[1] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  CCM must indicate complete (CCM_RDY = 0 (YES)).\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Check Data B bit 7 if reserved bit is set
	if ( pPid->Data[1] & 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Reserved I/M readiness Data B bit 7 set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Evaluate Data C, BIT 0 - HCCAT/CAT_SUP
	if ( pPid->Data[2] & 0x01 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_C_BIT_0;
	}

	// Evaluate Data C, BIT 2 - EVAP_SUP/Reserved
	if ( pPid->Data[2] & 0x04 )
	{
		if ( gstUserInput.eFuelType == GASOLINE &&
		     (gstUserInput.eComplianceType == US_OBDII ||
		      gstUserInput.eComplianceType == HD_OBD   ||
		      gstUserInput.eComplianceType == CNOBD) )
		{
			IMBitSupportFlags = IMBitSupportFlags | DATA_C_BIT_2;
		}
		else if ( gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Reserved I/M readiness Data C bit 2 set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Evaluate Data C, BIT 3 - AIR/BP_SUP
	if ( pPid->Data[2] & 0x08 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_C_BIT_3;
	}

	// Evaluate Data C, BIT 4 - GPF_SUP/Reserved
	if ( pPid->Data[2] & 0x10 &&
	     gstUserInput.eComplianceType != CNOBD &&
	     gstUserInput.eComplianceType != EOBD &&
	     gstUserInput.eComplianceType != EOBD_NO_IUMPR &&
	     gstUserInput.eComplianceType != HD_EOBD &&
	     gstUserInput.eComplianceType != US_OBDII &&
	     gstUserInput.eComplianceType != HD_OBD &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Reserved I/M readiness Data C bit 4 set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Evaluate Data C, BIT 5 - O2S/EGS_SUP
	if ( pPid->Data[2] & 0x20 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_C_BIT_5;
	}

	// Evaluate Data C, BIT 6 - HTR/PM_SUP
	if ( pPid->Data[2] & 0x40 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_C_BIT_6;
	}

	// Evaluate Data C, BIT 7 - EGR_SUP
	if ( pPid->Data[2] & 0x80 )
	{
		IMBitSupportFlags = IMBitSupportFlags | DATA_C_BIT_7;
	}

	// Evaluate Data D, BIT 2 - EVAP_RDY/Reserved
	if ( (pPid->Data[3] & 0x04) == 0x04 &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Reserved I/M readiness Data D bit 2 set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Evaluate Data D, BIT 4 - GPF_RDY/Reserved
	if ( pPid->Data[3] & 0x10 &&
	     gstUserInput.eComplianceType != CNOBD &&
	     gstUserInput.eComplianceType != EOBD &&
	     gstUserInput.eComplianceType != EOBD_NO_IUMPR &&
	     gstUserInput.eComplianceType != HD_EOBD &&
	     gstUserInput.eComplianceType != US_OBDII &&
	     gstUserInput.eComplianceType != HD_OBD &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Reserved I/M readiness Data D bit 4 set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( gbEngineRunning == FALSE && geTestPhase != eTestPerformanceCounters )  // test 5.6 & 10.6
	{
		// supported monitors should not be complete (except O2 on Gasoline)
		// DATA_D Bit 0
		if ( (pPid->Data[2] & 0x01) == 0x01 &&
		     (pPid->Data[3] & 0x01) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "HCCAT" : "CAT",
			      gstUserInput.eFuelType == DIESEL ? "HCCAT" : "CAT" );
		}

		// DATA_D Bit 1
		if ( (pPid->Data[2] & 0x02) == 0x02 &&
		     (pPid->Data[3] & 0x02) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "NCAT" : "HCAT",
			      gstUserInput.eFuelType == DIESEL ? "NCAT" : "HCAT" );
		}

		// DATA_D Bit 2
		if ( (pPid->Data[2] & 0x04) == 0x04 &&
		     (pPid->Data[3] & 0x04) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "RESERVED2" : "EVAP",
			      gstUserInput.eFuelType == DIESEL ? "RESERVED2" : "EVAP" );
		}

		// DATA_D Bit 3
		if ( (pPid->Data[2] & 0x08) == 0x08 &&
		     (pPid->Data[3] & 0x08) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "BP" : "AIR",
			      gstUserInput.eFuelType == DIESEL ? "BP" : "AIR" );
		}

		// DATA_D Bit 4
		if ( (pPid->Data[2] & 0x10) == 0x10 &&
		     (pPid->Data[3] & 0x10) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s = 1 (YES)) must indicate incomplete (%s = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "RESERVED" : "GPF_SUP",
			      gstUserInput.eFuelType == DIESEL ? "RESERVED" : "GPF_RDY" );
		}

		// DATA_D Bit 5
		if ( (pPid->Data[2] & 0x20) == 0x20 &&
		     (pPid->Data[3] & 0x20) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "EGS" : "O2S",
			      gstUserInput.eFuelType == DIESEL ? "EGS" : "O2S" );
		}

		// DATA_D Bit 6
		if ( (pPid->Data[2] & 0x40) == 0x40 &&
		     (pPid->Data[3] & 0x40) == 0x00 &&
		     gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gstUserInput.eFuelType == DIESEL ? "PM" : "HTR",
			      gstUserInput.eFuelType == DIESEL ? "PM" : "HTR" );
		}

		// DATA_D Bit 7
		if ( (pPid->Data[2] & 0x80) == 0x80 &&
		     (pPid->Data[3] & 0x80) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitor (EGR_SUP = 1 (YES)) must indicate incomplete (EGR_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ) );
		}
	}


	// unsupported monitors should be complete
	// DATA_D Bit 0
	if ( (pPid->Data[2] & 0x01) == 0x00 &&
	     (pPid->Data[3] & 0x01) == 0x01 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (%s_SUP = N) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gstUserInput.eFuelType == DIESEL ? "HCCAT" : "CAT",
		      gstUserInput.eFuelType == DIESEL ? "HCCAT" : "CAT" );
	}

	// DATA_D Bit 1
	if ( (pPid->Data[2] & 0x02) == 0x00 &&
	     (pPid->Data[3] & 0x02) == 0x02 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gstUserInput.eFuelType == DIESEL ? "NCAT" : "HCAT",
		      gstUserInput.eFuelType == DIESEL ? "NCAT" : "HCAT" );
	}

	// DATA_D Bit 2
	if ( (pPid->Data[2] & 0x04) == 0x00 &&
	     (pPid->Data[3] & 0x04) == 0x04 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gstUserInput.eFuelType == DIESEL ? "RESERVED2" : "EVAP",
		      gstUserInput.eFuelType == DIESEL ? "RESERVED2" : "EVAP" );
	}

	// DATA_D Bit 3
	if ( (pPid->Data[2] & 0x08) == 0x00 &&
	     (pPid->Data[3] & 0x08) == 0x08 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gstUserInput.eFuelType == DIESEL ? "BP" : "AIR",
		      gstUserInput.eFuelType == DIESEL ? "BP" : "AIR" );
	}

	// DATA_D Bit 4
	if ( (pPid->Data[2] & 0x10) == 0x00 &&
	     (pPid->Data[3] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (RESERVED Byte C Bit 4 = 0) must indicate complete (RESERVED Byte D Bit 4 = 0)\n",
		      GetEcuId ( EcuIdx ) );
	}

	// DATA_D Bit 5
	if ( (pPid->Data[2] & 0x20) == 0x00 &&
	     (pPid->Data[3] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gstUserInput.eFuelType == DIESEL ? "EGS" : "O2S",
		      gstUserInput.eFuelType == DIESEL ? "EGS" : "O2S" );
	}

	// DATA_D Bit 6
	if ( (pPid->Data[2] & 0x40) == 0x00 &&
	     (pPid->Data[3] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gstUserInput.eFuelType == DIESEL ? "PM" : "HTR",
		      gstUserInput.eFuelType == DIESEL ? "PM" : "HTR" );
	}

	// DATA_D Bit 7
	if ( (pPid->Data[2] & 0x80) == 0x00 &&
	     (pPid->Data[3] & 0x80) == 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F401  Unsupported monitor (EGR_SUP = 0 (NO)) must indicate complete (EGR_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( geTestPhase == eTestPerformanceCounters )
	{
		if ( pPid->Data[3] != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  $F401  Supported monitors (SUP = 1 (YES)) must be complete (RDY = 0 (YES)) after I/M drive cycle\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}




/*******************************************************************************
**
**  Function:  VerifyPidxxData
**
**  Purpose:   Display and evaluate PID $F4/5xx data
**
*******************************************************************************/
void VerifyPid03Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F403  FUELSYSA = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Fuel System A Status bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL          = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CL          = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Drive    = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Fault    = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CL-Fault    = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL_B2       = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Drive_B2 = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Fault_B2 = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F403  FUELSYSB = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );
	// Fuel System B Status bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL          = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CL          = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Drive    = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Fault    = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CL-Fault    = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL_B2       = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Drive_B2 = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    OL-Fault_B2 = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == FALSE &&  // if Test 5.6  AND
	     ((pPid->Data[0] & 0x02) != 0 ||                      // FUELSYSA Closed Loop OR
	      (pPid->Data[1] & 0x02) != 0) )                      // FUELSYSB Closed Loop
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FUELSYSA Bit 1 and FUELSYSB Bit 1 must both be 0 (not Closed Loop)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid04Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(pPid->Data[0]) * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F404  LOAD_PCT = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( gbHybrid != TRUE )
			{
				// don't range check hybrids at idle, as LOAD_PCT could be up to 100%
				if ( TempData_float == 0 || TempData_float > 60 )
				{
					// Load should be 60% or less with engine running
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  LOAD_PCT should be 60 %% or less (but not 0) with engine running\n\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
		else  // test 5.6
		{
			if ( TempData_float != 0 )
			{
				// There should be no load with the engine OFF
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  LOAD_PCT > 0 %% (There should be no load with the engine OFF)\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid05Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 40;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F405  ECT      = %d C\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_long < -20 || TempData_long > 120 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ECT outside expected range (-20 to 120)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid06Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F406  SHRTFT1  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
	{
		if ( TempData_float < -50.0 || TempData_float > 50.0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SHRTFT1 outside expected range (-50 to 50)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F406  SHRTFT3  = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
		{
			if ( TempData_float < -50.0 || TempData_float > 50.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SHRTFT3 outside expected range (-50 to 50)\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid07Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F407  LONGFT1  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
	{
		if ( TempData_float < -50.0 || TempData_float > 50.0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  LONGFT1 outside expected range (-50 to 50)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F407  LONGFT3  = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
		{
			if ( TempData_float < -50.0 || TempData_float > 50.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  LONGFT3 outside expected range (-50 to 50)\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid08Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F408  SHRTFT2  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
	{
		if ( TempData_float < -50.0 || TempData_float > 50.0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SHRTFT2 outside expected range (-50 to 50)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F407  SHRTFT4  = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
		{
			if ( TempData_float < -50.0 || TempData_float > 50.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SHRTFT4 outside expected range (-50 to 50)\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid09Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F409  LONGFT2  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
	{
		if ( TempData_float < -50.0 || TempData_float > 50.0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  LONGFT2 outside expected range (-50 to 50)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F407  LONGFT4  = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
		{
			if ( TempData_float < -50.0 || TempData_float > 50.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  LONGFT4 outside expected range (-50 to 50)\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid0AData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] * 3;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F40A  FRP      = %u kPa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_long == 0 && gbHybrid != TRUE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FRP must be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid0BData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(pPid->Data[0]);
	if ( bPid4FSupported == TRUE && Pid4F[EcuIdx][3]!=0 )
	{
		TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][3]*10)/255);
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F40B  MAP      = %.1f kPa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_float == 0.0 && gbHybrid != TRUE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MAP should be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid0CData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = ((pPid->Data[0] << 8) +
	                  pPid->Data[1]) / 4;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F40C  RPM      = %d rpm\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			// if idle RPM is outside the reasonable range
			if ( TempData_long > 2000 || TempData_long < 300 )
			{
				// Gas, Deisel vehicle
				if ( gbHybrid == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  RPM outside expected range (300 - 2000)\n",
					      GetEcuId ( EcuIdx ) );
				}

				// HEV, PHEV, S/S vehicle
				else if ( TempData_long != 0 )
				{
					if (  TempData_long >= 1 && TempData_long < 300  )
					{
						Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  RPM outside expected range (1 - 300)\n",
						      GetEcuId ( EcuIdx ) );
					}
					else
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  RPM outside expected range (1 - 300)\n",
						      GetEcuId ( EcuIdx ) );
					}
				}
			}
		}
		else  // test 5.6
		{
			if ( TempData_long != 0 )
			{
				// There should be no RPM with the engine OFF
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  RPM should be 0 with engine Off\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid0DData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F40D  VSS      = %d km/h\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	if ( pPid->Data[0] != 0x00 )
	{
		// There should be no vehicle speed when not moving
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  VSS > 0 km/h (There should be no vehicle speed when not moving)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid0EData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = ((float)pPid->Data[0] / (float)2.0) - (float)64.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F40E  SPARKADV = %.1f deg\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
	{
		if ( TempData_float < -35 || TempData_float > 55 )
		{
			if ( gbHybrid == FALSE )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SPARKADV outside expected range (-35 to 55)\n",
				      GetEcuId ( EcuIdx ) );
			}

			// HEV, PHEV, S/S vehicle
			else
			{
				Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SPARKADV outside expected range (-35 to 55)\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid0FData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 40;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F40F  IAT      = %d C\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_long < -20 || TempData_long > 120 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  IAT outside expected range (-20 to 120)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid10Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1]);
	if ( bPid50Supported == TRUE && Pid50[EcuIdx][0] != 0 )
	{
		TempData_float = TempData_float * ((float)(Pid50[EcuIdx][0] * 10) / 65535);
	}
	else
	{
		TempData_float = TempData_float / (float)100.0;
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F410  MAF      = %.2f g/s\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( TempData_float == 0.0 && gbHybrid != TRUE )
			{
				// MAF should not be zero with the engine running
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  MAF should not be zero with the engine running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		else  // test 5.6, engine off
		{
			if ( TempData_float > 5.0 )
			{
				// MAF should be zero with the engine OFF
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  MAF should be less than 5 g/s with the engine OFF\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid11Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F411  TP       = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eFuelType == GASOLINE )
	{
		// non-diesel
		if ( TempData_float > 50 )
		{
			// Throttle position should be 40% or less when not driving
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TP should be 50 %% or less when not driving\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eFuelType == DIESEL )
	{
		// diesel
		if ( TempData_float > 100 )
		{
			// Throttle position should be 100% or less when not driving
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TP should be 100 %% or less when not driving\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid12Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F412  AIR_STAT = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
}


/*
case 0x13:  See 0x1D
*/


void VerifyPid14__1BData ( BYTE EcuIdx, PID *pPid )
{
	BYTE           BSIndex;


	switch ( pPid->PIDLSB )
	{
		case 0x14:
			BSIndex = 0x11;
		break;
		case 0x15:
			BSIndex = 0x12;
		break;
		case 0x16:
			BSIndex = bPid13Supported ? 0x13 : 0x21;
		break;
		case 0x17:
			BSIndex = bPid13Supported ? 0x14 : 0x22;
		break;
		case 0x18:
			BSIndex = bPid13Supported ? 0x21 : 0x31;
		break;
		case 0x19:
			BSIndex = bPid13Supported ? 0x22 : 0x32;
		break;
		case 0x1A:
			BSIndex = bPid13Supported ? 0x23 : 0x41;
		break;
		case 0x1B:
			BSIndex = bPid13Supported ? 0x24 : 0x42;
		break;
	}

	TempData_float = (float)pPid->Data[0] * (float).005;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  O2S%x    = %.3f V\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );

	TempData_float = ((float)(pPid->Data[1]) * (float)(100.0 / 128.0)) - (float)100.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  SHRTFT%x = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );
}


void VerifyPid1CData ( BYTE EcuIdx, PID *pPid )
{
	// Make sure value is in the valid range before the lookup
	if ( pPid->Data[0] >= MAX_OBD_TYPES )
	{
		pPid->Data[0] = 0;
	}

	// Vehicle should support OBD-II
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F41C  OBDSUP   = $%02X (%s)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0],
	      szOBD_TYPE[pPid->Data[0]] );

	if ( gstUserInput.eComplianceType == US_OBDII )
	{
		if ( pPid->Data[0] != 0x01 &&     // CARB OBD II
		     pPid->Data[0] != 0x03 &&     // OBDI and OBD II
		     pPid->Data[0] != 0x07 &&     // EOBD and OBD II
		     pPid->Data[0] != 0x09 &&     // EOBD, OBD and OBD II
		     pPid->Data[0] != 0x0B &&     // JOBD and OBD II
		     pPid->Data[0] != 0x0D &&     // JOBD, EOBD, and OBD II
		     pPid->Data[0] != 0x0F &&
		     pPid->Data[0] != 0x22 )      // OBD, OBD II and HD_OBD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Light Duty OBD II ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eComplianceType == HD_OBD )
	{
		if ( pPid->Data[0] != 0x13 &&     // HD OBD-C
		     pPid->Data[0] != 0x14 &&     // HD OBD
		     pPid->Data[0] != 0x22 &&     // OBD, OBD II and HD_OBD
		     pPid->Data[0] != 0x38 &&     // Heavy Duty ZEV, CARB ZEP
		     pPid->Data[0] != 0x3B )      // EPA HD OBD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Heavy Duty OBD II ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eComplianceType == EOBD ||
	          gstUserInput.eComplianceType == EOBD_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x06 &&     // EOBD
		     pPid->Data[0] != 0x07 &&     // EOBD and OBD II
		     pPid->Data[0] != 0x08 &&     // EOBD and OBD
		     pPid->Data[0] != 0x09 &&     // EOBD, OBD and OBD II
		     pPid->Data[0] != 0x0C &&     // JOBD and EOBD
		     pPid->Data[0] != 0x0D &&     // JOBD, EOBD, and OBD II
		     pPid->Data[0] != 0x0E &&     // EURO IV B1
		     pPid->Data[0] != 0x0F )      // EURO V B2
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Light Duty EOBD ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eComplianceType == HD_EOBD )
	{
		if ( pPid->Data[0] != 0x17 &&     // HD EOBD-I
		     pPid->Data[0] != 0x18 &&     // HD EOBD-I N
		     pPid->Data[0] != 0x19 &&     // HD EOBD-II
		     pPid->Data[0] != 0x1A &&     // HD EOBD-II N
		     pPid->Data[0] != 0x21 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Heavy Duty EOBD ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eComplianceType == IOBD_NO_IUMPR || gstUserInput.eComplianceType == HD_IOBD_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x20 &&      // IOBD BS4
		     pPid->Data[0] != 0x2D &&      // IOBD BS6
		     pPid->Data[0] != 0x2E )       // IOBD BSVI HD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a IOBD II ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eComplianceType == OBDBr_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x1C &&    // OBDBr-1
		     pPid->Data[0] != 0x1D &&    // OBDBr-2
		     pPid->Data[0] != 0x23 &&    // OBDBr-3
		     pPid->Data[0] != 0x2A &&    // OBDBr-7
		     pPid->Data[0] != 0x2F )     // OBDBr-8
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a OBDBr ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eComplianceType == CNOBD )
	{
		if ( pPid->Data[0] != 0x29 &&   // China Nationwide Stage 6
		     pPid->Data[0] != 0x2B &&   // China Heavy Duty VI
		     pPid->Data[0] != 0x32 )    // China Off-Road IV OBD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a CNOBD ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else if ( gstUserInput.eEnergyType == ZEV )
	{
		if ( pPid->Data[0] != 0x33 &&     // CARB ACC-II
		     pPid->Data[0] != 0x38 &&     // Heavy Duty ZEV, CARB ZEP
		     pPid->Data[0] != 0x39 &&     // CARB ACC-II & EPA TIER 4 
		     pPid->Data[0] != 0x3A )      // EPA Tier 4 (GTR 22) 
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a ZEV ECU\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid13_1D ( BYTE EcuIdx, PID *pPid )
{
	unsigned short O2Bit;
	unsigned short O2Count;

	// Identify support for PID 0x13 / 0x1D
	if ( pPid->PIDLSB == 0x13 )
	{
		bPid13Supported = TRUE;
	}
	else
	{
		bPid1DSupported = TRUE;
	}

	// Evaluate for dual PID / Gasoline engine support
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bPid13Supported == TRUE &&
	     bPid1DSupported == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F413 & $F41D both indicated as supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Count the number of O2 sensors
	for ( O2Bit = 0x01, O2Count = 0;
	      O2Bit != 0x100;
	      O2Bit = O2Bit << 1 )
	{
		if ( pPid->Data[0] & O2Bit )
		{
			O2Count++;
		}
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  O2SLOC   = $%02X (%d O2 Sensors)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      pPid->Data[0],
	      O2Count );

	// At least 2 O2 sensors required for Gasoline engines
	if ( gstUserInput.eFuelType == GASOLINE &&
	     O2Count < 2 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  O2S < 2 (At least 2 O2 sensors required for Gasoline engines)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid1EData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F41E  PTO_STAT = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
}


void VerifyPid1FData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = ((pPid->Data[0] << 8) +
	                  pPid->Data[1]);
	GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F41F  RUNTM    = %d sec (%d hrs, %d mins, %d secs)\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long,
	      hours, mins, secs );

	if ( bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )
		{
			if ( gbEngineWarm == TRUE )  // test 10.13
			{
				if ( TempData_long <= 300 )
				{
					// Run time should be greater than 300 seconds
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  RUNTM should be greater than 300 seconds\n",
					      GetEcuId ( EcuIdx ),
					      TempData_long );
				}
			}
			else  // test 5.10
			{
				if ( TempData_long == 0 && gbHybrid != TRUE )
				{
					// Run time should not be zero if engine is running
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  RUNTM should not be zero if engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
		else  // test 5.6
		{
			if ( TempData_long != 0 )
			{
				// Run time should be zero if engine is OFF
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  RUNTM should be zero if engine is OFF\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid21Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = ((pPid->Data[0] << 8) +
	                  pPid->Data[1]);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F421  MIL_DIST = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( bEngineDontCare == FALSE &&  // NOT Test 10.2 and
	     gbEngineWarm    == FALSE &&  // NOT Test 10.13 and
	     gbPSA           == FALSE )   // NOT Test 12.6
	{
		if ( (gstUserInput.eEnergyType  == ICE ||  // Test 5.6 or 5.10 or
		      (gstUserInput.eEnergyType == ZEV &&
		       gbPSA == FALSE)) &&                 // Test 12.3 or
		     TempData_long != 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MIL_DIST should not be greater than 0 after clearing DTCs\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid22Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1]) * (float)0.079;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F422  FRP (relative to manifold) = %.1f kPa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE &&  // NOT Test 10.2
	     gbEngineRunning == TRUE  &&  // test 5.10 & 10.13
	     gbHybrid != TRUE         &&  // not a hybrid vehicle
	     TempData_float == 0.0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FRP should be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid23Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = ((pPid->Data[0] << 8) +
	                  pPid->Data[1]) * 10;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F423  FRP      = %lu kPa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE &&  // NOT Test 10.2
	     gbEngineRunning == TRUE  &&  // test 5.10 & 10.12
	     gbHybrid != TRUE         &&  // not a hybrid vehicle
	     TempData_long == 0  )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FRP should be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid24__2BData ( BYTE EcuIdx, PID *pPid )
{
	BYTE           BSIndex;


	switch ( pPid->PIDLSB )
	{
		case 0x24:
			BSIndex = 0x11;
		break;
		case 0x25:
			BSIndex = 0x12;
		break;
		case 0x26:
			BSIndex = bPid13Supported ? 0x13 : 0x21;
		break;
		case 0x27:
			BSIndex = bPid13Supported ? 0x14 : 0x22;
		break;
		case 0x28:
			BSIndex = bPid13Supported ? 0x21 : 0x31;
		break;
		case 0x29:
			BSIndex = bPid13Supported ? 0x22 : 0x32;
		break;
		case 0x2A:
			BSIndex = bPid13Supported ? 0x23 : 0x41;
		break;
		case 0x2B:
			BSIndex = bPid13Supported ? 0x24 : 0x42;
		break;
	}

	TempData_float = (float)((unsigned long)(pPid->Data[0] << 8) +
	                                         pPid->Data[1]);
	if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][0] == 0 )
	{
		TempData_float = TempData_float * (float)0.0000305;
	}
	else
	{
		TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][0])/65535);
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  EQ_RAT%x = %.3f %%\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );

	TempData_float = (float)((unsigned long)(pPid->Data[2] << 8) +
	                                         pPid->Data[3]);
	if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][1] == 0 )
	{
		TempData_float = TempData_float * (float)0.000122;
	}
	else
	{
		TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][1])/65535);
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  O2S%x    = %.3f V\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );
}


void VerifyPid2CData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F42C  EGR_PCT  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     gbEngineRunning == FALSE )  // test 5.6
	{
		if ( TempData_float > 10 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EGR_PCT should be less than 10 %%\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	else  // test 5.10 & 10.13
	{
		// Diesel engine
		if ( gstUserInput.eFuelType == DIESEL )
		{
			if ( TempData_float > 100)
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGR_PCT should be less than 100 %%\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		// Gasoline engine
		else if ( gstUserInput.eFuelType == GASOLINE )
		{
			if ( gbHybrid == FALSE && TempData_float > 10 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGR_PCT should be less than 10 %%\n",
				      GetEcuId ( EcuIdx ) );
			}
			else if ( gbHybrid == TRUE && TempData_float > 50 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGR_PCT should be less than 50 %%\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid2DData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = ( (float)pPid->Data[0] * (float)(100.0/128.0) ) - (float)100.0;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F42D  EGR_ERR  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid2EData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0/255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F42E  EVAP_PCT = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid2FData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = ((float)pPid->Data[0]) * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F42F  FLI      = %.1f\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float < 1.0 || TempData_float > 100.0 )
	{
		Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FLI outside expected range (1 to 100)\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid30Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F430  WARM_UPS = %d\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( bEngineDontCare == FALSE &&  // NOT Test 10.2 and
	     gbPSA           == FALSE )   // NOT Test 12.6
	{
		if ( gbEngineWarm == TRUE &&  // test 10.13
		     TempData_long > 4 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  WARM_UPS should be less than or equal to 4\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( ((gstUserInput.eEnergyType == ICE &&
		            gbEngineRunning == FALSE) ||        // Test 5.6 or
		           (gstUserInput.eEnergyType == ZEV &&
		            gbPSA == FALSE)) &&                  // Test 12.3
		          TempData_long > 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  WARM_UPS should be less than or equal to 0 after clearing DTCs\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eEnergyType == ICE &&
		          gbEngineRunning == TRUE &&           // Test 5.10
		          TempData_long > 1 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  WARM_UPS should be less than or equal to 1\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid31Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = (pPid->Data[0] << 8) +
	                 pPid->Data[1];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F431  CLR_DIST = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( bEngineDontCare == FALSE &&  // NOT Test 10.2 and
	     gbPSA == FALSE )             // NOT Test 12.6
	{
		if ( gbEngineWarm == TRUE &&  // Test 10.13
		     TempData_long >= 50 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CLR_DIST should be less than 50 km after CARB drive cycle\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( (gstUserInput.eEnergyType  == ICE ||  // Test 5.6 or 5.10
		           (gstUserInput.eEnergyType == ZEV &&
		            gbPSA == FALSE)) &&                 // Test 12.3 or
		          TempData_long != 00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CLR_DIST should be 0 km after clearing DTCs\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid32Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)((signed short)((pPid->Data[0] << 8) +
	                                         pPid->Data[1] ) ) * (float).25;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F432  EVAP_VP  = %.1f Pa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid33Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F433  BARO     = %d kPa\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] < 71 || pPid->Data[0] > 110 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  BARO outside expected range (71 to 110)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid34__3BData ( BYTE EcuIdx, PID *pPid )
{
	BYTE           BSIndex;


	switch ( pPid->PIDLSB )
	{
		case 0x34:
			BSIndex = 0x11;
		break;
		case 0x35:
			BSIndex = 0x12;
		break;
		case 0x36:
			BSIndex = bPid13Supported ? 0x13 : 0x21;
		break;
		case 0x37:
			BSIndex = bPid13Supported ? 0x14 : 0x22;
		break;
		case 0x38:
			BSIndex = bPid13Supported ? 0x21 : 0x31;
		break;
		case 0x39:
			BSIndex = bPid13Supported ? 0x22 : 0x32;
		break;
		case 0x3A:
			BSIndex = bPid13Supported ? 0x23 : 0x41;
		break;
		case 0x3B:
			BSIndex = bPid13Supported ? 0x24 : 0x42;
		break;
	}

	// scale Equivalence Ratio
	TempData_float = (float)((unsigned long)(pPid->Data[0] << 8) +
	                                         pPid->Data[1]);
	if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][0] == 0 )
	{
		TempData_float = TempData_float * (float)0.0000305;
	}
	else
	{
		TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][0])/65535);
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  EQ_RAT%x = %.3f %%\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );

	// offset and scale Oxygen Sensor Current
	TempData_float = (float)((((signed short)(pPid->Data[2]) << 8) +
	                                          pPid->Data[3]) - 0x8000);
	if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][2] == 0 )
	{
		TempData_float = TempData_float * (float)0.00390625;
	}
	else
	{
		TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][2])/32768);
	}
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  O2S%x    = %.2f mA\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );
}


void VerifyPid3C__3FData ( BYTE EcuIdx, PID *pPid )
{
	BYTE           BSIndex;


	switch ( pPid->PIDLSB )
	{
		case 0x3C:
			BSIndex = 0x11;
		break;
		case 0x3D:
			BSIndex = 0x21;
		break;
		case 0x3E:
			BSIndex = 0x12;
		break;
		case 0x3F:
			BSIndex = 0x22;
		break;
	}
	TempData_float = ((float)((pPid->Data[0] << 8) +
	                           pPid->Data[1] ) * (float).1 ) - (float)(40.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4%02X  CATEMP%X = %.1f C\n",
	      GetEcuId ( EcuIdx ),
	      pPid->PIDLSB,
	      BSIndex,
	      TempData_float );
}


void VerifyPid41Data ( BYTE EcuIdx, PID *pPid, BOOL bEngineDontCare )
{
#define  MAX_STRING_NUMBER  8
#define  MAX_NAME_LENGTH    12

	unsigned int ByteIdx;
	unsigned int BitIndex;
	unsigned int BitMask;
	unsigned int BitMask2;
	char         String[MAX_STRING_NUMBER][MAX_NAME_LENGTH];
	BYTE         StringIndex;


	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F441  Monitor Status  Byte A = $%02X  B = $%02X  C = $%02X  D = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0],
	      pPid->Data[1],
	      pPid->Data[2],
	      pPid->Data[3] );

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      "MIS_ENA",   (pPid->Data[1] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "MIS_CMPL",  (pPid->Data[1] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      "FUEL_ENA",  (pPid->Data[1] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "FUEL_CMPL", (pPid->Data[1] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      "CCM_ENA",   (pPid->Data[1] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "CCM_CMPL",  (pPid->Data[1] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "HCCAT_ENA"  : "CAT_ENA",  (pPid->Data[2] & 0x01) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "HCCAT_CMPL" : "CAT_CMPL", (pPid->Data[3] & 0x01) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "NCAT_ENA"  : "HCAT_ENA",  (pPid->Data[2] & 0x02) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "NCAT_CMPL" : "HCAT_CMPL", (pPid->Data[3] & 0x02) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "reserved" : "EVAP_ENA",   (pPid->Data[2] & 0x04) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "reserved" : "EVAP_CMPL",  (pPid->Data[3] & 0x04) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "BP_ENA"  : "AIR_ENA",     (pPid->Data[2] & 0x08) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "BP_CMPL" : "AIR_CMPL",    (pPid->Data[3] & 0x08) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "reserved" : "GPF_ENA",    (pPid->Data[2] & 0x10) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "reserved" : "GPF_CMPL",   (pPid->Data[3] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "EGS_ENA"  : "O2S_ENA",    (pPid->Data[2] & 0x20) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "EGS_CMPL" : "O2S_CMPL",   (pPid->Data[3] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "PM_ENA"  : "HTR_ENA",     (pPid->Data[2] & 0x40) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "PM_CMPL" : "HTR_CMPL",    (pPid->Data[3] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-10s = %s\n",
	      "EGR_ENA",   (pPid->Data[2] & 0x80) ? "1 (YES)" : "0 (NO)",
	      "EGR_CMPL",  (pPid->Data[3] & 0x80) ? "1 (NO)"  : "0 (YES)" );


	// check that bits set in PID $41 match support in PID $01
	for ( ByteIdx = 1;
	      ByteIdx <= 3;
	      ByteIdx++ )
	{
		if ( ByteIdx == 1 )
		{
			strcpy_s ( String[0], MAX_NAME_LENGTH, "MIS" );
			strcpy_s ( String[1], MAX_NAME_LENGTH, "FUEL" );
			strcpy_s ( String[2], MAX_NAME_LENGTH, "CCM" );
			strcpy_s ( String[3], MAX_NAME_LENGTH, "no display" );
			strcpy_s ( String[4], MAX_NAME_LENGTH, "MIS" );
			strcpy_s ( String[5], MAX_NAME_LENGTH, "FUEL" );
			strcpy_s ( String[6], MAX_NAME_LENGTH, "CCM" );
			strcpy_s ( String[7], MAX_NAME_LENGTH, "reserved" );

			BitMask2 = 0x01;
		}
		else
		{
			strcpy_s ( String[0], MAX_NAME_LENGTH, gstUserInput.eFuelType == DIESEL ? "HCCAT"    : "CAT" );
			strcpy_s ( String[1], MAX_NAME_LENGTH, gstUserInput.eFuelType == DIESEL ? "NCAT"     : "HCAT" );
			strcpy_s ( String[2], MAX_NAME_LENGTH, gstUserInput.eFuelType == DIESEL ? "reserved" : "EVAP" );
			strcpy_s ( String[3], MAX_NAME_LENGTH, gstUserInput.eFuelType == DIESEL ? "BP"       : "AIR" );
			strcpy_s ( String[4], MAX_NAME_LENGTH, "reserved" );
			strcpy_s ( String[5], MAX_NAME_LENGTH, gstUserInput.eFuelType == DIESEL ? "EGS"      : "O2S" );
			strcpy_s ( String[6], MAX_NAME_LENGTH, gstUserInput.eFuelType == DIESEL ? "PM"       : "HTR" );
			strcpy_s ( String[7], MAX_NAME_LENGTH, "EGR" );

			BitMask2 = 0x01;
		}


		for ( BitIndex = 0, BitMask = 0x01, StringIndex = 0;
		      BitIndex < 8;
		      BitIndex++, BitMask <<= 1, StringIndex++ )
		{
			// reserved bit check
			if ( (ByteIdx == 1 && BitIndex == 7 && (pPid->Data[1] & BitMask) == BitMask) ||  // reserved bit is set
			     (ByteIdx == 2 && BitIndex == 4 && (pPid->Data[2] & BitMask) == BitMask) ||  // reserved bit is set
			     (ByteIdx == 3 && BitIndex == 4 && (pPid->Data[3] & BitMask) == BitMask) )   // reserved bit is set
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  PID $F441  Reserved Bit (Byte %c Bit %d) set (1) (must be clear (0))\n",
				      GetEcuId ( EcuIdx ),
				      'A'+ ByteIdx,
				      BitIndex );
			}

			// Diesel bit check
			// Diesel bit should match user input
			else if ( ByteIdx == 1 && BitIndex == 3 )
			{
				//  check if ECU does not only supports CCM requirements (PID $F401 Data B bit 2==1)
				if ( (gstResponse[EcuIdx].PIDF501.Data[1] & 0x03) != 0x00 ||
				     (gstResponse[EcuIdx].PIDF501.Data[2] & 0xFF) != 0x00 )
				{
					if ( (pPid->Data[1] & 0x08) == 0x00 &&
					     gstUserInput.eFuelType == DIESEL )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  PID $F441  Data B bit 3 clear (Gasoline) does not match user input (Diesel)\n",
						      GetEcuId ( EcuIdx ) );
					}
					else if ( (pPid->Data[1] & 0x08) == 0x08 &&
					          (gstUserInput.eFuelType == GASOLINE) )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  PID $F441  Data B bit 3 set (Diesel) does not match user input (Non Diesel)\n",
						      GetEcuId ( EcuIdx ) );
					}
				}
			}

			// Enable/Support bit check
			// enabled monitors should be supported
			else if ( ( ( ByteIdx == 1 && BitIndex >= 0 && BitIndex <=2 ) ||
			            ByteIdx == 2 ) &&
			          (pPid->Data[ByteIdx] & BitMask) == BitMask  &&      // enabled       in PID $41
			          (gstResponse[EcuIdx].PIDF501.Data[ByteIdx] & BitMask) == 0x00 )  // not supported in PID $01
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  If monitor enabled (%s_ENA = 1 (YES)) in PID $F441 it must indicate supported (%s_SUP = 1 (YES)) in PID $F401\n",
				      GetEcuId ( EcuIdx ),
				      String[StringIndex],
				      String[StringIndex] );
			}


			else
			{
				// Incomplete/Supported bit check
				// incomplete monitors should be supported
				if ( (pPid->Data[ByteIdx] & BitMask) == BitMask &&                                                           // not complete  in PID $41
				     ( ( ByteIdx == 1 && BitIndex >= 4 && BitIndex <=6 && (gstResponse[EcuIdx].PIDF501.Data[1] & BitMask2) == 0x00 ) ||   // not supported in PID $01
				       ( ByteIdx == 3 &&                                  (gstResponse[EcuIdx].PIDF501.Data[2] & BitMask)  == 0x00 ) ) )  // not supported in PID $01
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  If monitor not complete (%s_CMPL = 1 (NO)) in DID $F441 it must indicate supported (%s_SUP = 1 (YES)) in PID $F401\n",
					      GetEcuId ( EcuIdx ),
					      String[StringIndex],
					      String[StringIndex] );
				}
				if ( ByteIdx == 1 && BitIndex >= 4 && BitIndex <=6 )
				{
					BitMask2<<=1;
				}


				// Byte 3 (D) only checks
				if ( ByteIdx == 3 )
				{
					// Supported/Incomplete bit check
					// supported monitors should be incomplete (when engine off)
					if ( bEngineDontCare == FALSE && gbEngineRunning == FALSE &&  // test 5.6 ONLY; NOT Test 5.10, 10.2 & 10.13
					     (gstResponse[EcuIdx].PIDF501.Data[2] & BitMask) == BitMask &&   // supported in PID $01
					     (gstResponse[EcuIdx].PIDF501.Data[3] & BitMask) == 0x00 )       // complete  in PID $41
					{
						// O2 Heater monitor is allowed to complete for gasoline vehicles
						if ( BitIndex != 6 ||
						     gstUserInput.eFuelType == DIESEL )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  If monitor supported (%s_SUP = 1 (YES)) in PID $F401 it must indicate incomplete (%s_CMPL = 1 (NO)) in PID $F441\n",
							      GetEcuId ( EcuIdx ),
							      String[StringIndex],
							      String[StringIndex] );
						}
					}


					// Unupported/Complete bit check */
					// unsupported monitors should be complete
					if ( (gstResponse[EcuIdx].PIDF501.Data[2] & BitMask) == 0x00 &&    // not supported in PID $01
					     (pPid->Data[3] & BitMask) == BitMask )           // not complete  in PID $41
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  If monitor unsupported (%s_SUP = 0 (NO)) in PID $F401 it must indicate complete (%s_CMPL = 0 (YES)) in PID $F441\n",
						      GetEcuId ( EcuIdx ),
						      String[StringIndex],
						      String[StringIndex] );
					}
				}
			}
		}
	}
}


void VerifyPid42Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1] ) * (float).001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F442  VPWR     = %.3f V\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid43Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1] ) * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F443  LOAD_ABS = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( TempData_float == 0.0 && gbHybrid != TRUE )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  LOAD_ABS should be greater than 0 %% when engine is running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		else  // test 5.6
		{
			if ( TempData_float != 0.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  LOAD_ABS should be 0 %% when engine is not running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid44Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(((unsigned long)(pPid->Data[0]) << 8) +
	                                          pPid->Data[1]);
	if ( bPid4FSupported == FALSE ||
	     Pid4F[EcuIdx][0] == 0 )
	{
		TempData_float = TempData_float * (float)0.0000305;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F444  EQ_RAT   = %.3f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
		{
			if ( gstUserInput.eFuelType == GASOLINE &&
			     gbHybrid != TRUE )
			{
				if ( TempData_float < 0.5 || TempData_float > 1.5  )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EQ_RAT outside expected range (0.5 to 1.5)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}
	else
	{
		TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][0])/65535);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F444  EQ_RAT   = %.3f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid45Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F445  TP_R     = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eFuelType == GASOLINE &&
	     gbHybrid == FALSE &&
	     TempData_float > 50 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TP_R should be less than 50 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid46Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 40;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F446  AAT      = %d C\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_long < -20 || TempData_long > 85 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  AAT outside expected range (-20 to 85)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid47Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F447  TP_B     = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eFuelType == GASOLINE &&
	     gbHybrid == FALSE &&
	     TempData_float > 60 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TP_B should be less than 60 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid48Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F448  TP_C     = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eFuelType == GASOLINE &&
	     gbHybrid == FALSE &&
	     TempData_float > 60 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TP_C should be less than 60 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid49Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F449  APP_D    = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( TempData_float > 40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  APP_D should be less than 40 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid4AData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44A  APP_E    = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( TempData_float > 40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  APP_E should be less than 40 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid4BData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44B  APP_F    = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( TempData_float > 40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  APP_F should be less than 40 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid4CData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44C  TAC_PCT  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid4DData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = (pPid->Data[0] << 8) +
	                 pPid->Data[1];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44D  MIL_TIME = %d min\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( (gstUserInput.eEnergyType != ZEV ||       // NOT ZEV or
	      (gstUserInput.eEnergyType == ZEV &&      // ZEV and clear codes
	       bEngineDontCare == FALSE)) &&
	      gbEngineRunning == FALSE )   // test 5.6 and 12.5
	{
		if ( TempData_long != 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MIL_TIME should be 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid4EData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = (pPid->Data[0] << 8) +
	                 pPid->Data[1];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44E  CLR_TIME = %d min\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( bEngineDontCare == FALSE &&  // NOT Test 10.2 and
	     gbPSA           == FALSE )   // NOT Test 12.6
	{
		if ( gbEngineWarm == TRUE &&  // test 10.13
		     TempData_long < 5 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CLR_TIME should be greater than 5 min\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( (gstUserInput.eEnergyType  == ICE ||  // Test 5.6 or Test 5.10
		           (gstUserInput.eEnergyType == ZEV &&
		            gbPSA == FALSE)) &&                 // Test 12.3
		          TempData_long != 00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CLR_TIME should be 0 min after clearing DTCs\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid4FData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44F  EQ_RAT scaling      = %d / 65535\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44F  O2S Voltage scaling = %d * (1 V / 65535)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44F  O2S Current scaling = %d * (1 mA / 32768)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[2] );

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F44F  MAP scaling         = %d * (10 kPa / 255)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[3] );
}


void VerifyPid50Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F450  MAF scaling         = %d * (10 g/s / 65535)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
}


void VerifyPid51Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F451  FUEL_TYP = $%02X (%s)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0],
	      (pPid->Data[0] <= 0x1F ? szFUEL_TYPE[pPid->Data[0]] : szFUEL_TYPE[0x20]) );

	if ( gstUserInput.eComplianceType != US_ZEV )
	{
		if ( pPid->Data[0] == 0x00 ||
		     (pPid->Data[0] >= 0x0F && pPid->Data[0] <= 0x17) )
		{
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUEL_TYPE must be $01 to $0E or $18 to $1C\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( pPid->Data[0] >= 0x1D )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUEL_TYPE must be $01 to $0E or $18 to $1C\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid52Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F452  ALCH_PCT = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid53Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = ((pPid->Data[0] << 8) +
	                   pPid->Data[1] ) * (float)0.005;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F453  EVAP_VPA = %.3f kPa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid54Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = (long)((signed short)((pPid->Data[0] << 8) +
	                                       pPid->Data[1] ) );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F454  EVAP_VP  = %d Pa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPid55Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)( pPid->Data[0]  - 128 ) * (float)(100.0 / 128.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F455  STSO2FT1 = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float < -100.0 || TempData_float > 99.2 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  STSO2FT1 outside expected range (-100 to 99.2)\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float =  (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F455  STSO2FT3 = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -100.0 || TempData_float > 99.2 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  STSO2FT3 outside expected range (-100 to 99.2)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid56Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)( pPid->Data[0] - 128 ) * (float)(100.0 / 128.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F456  LGSO2FT1 = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float < -100.0 || TempData_float > 99.2 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  LGSO2FT1 outside expected range (-100 to 99.2)\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F456  LGSO2FT3 = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -100.0 || TempData_float > 99.2 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  LGSO2FT3 outside expected range (-100 to 99.2)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid57Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)( pPid->Data[0] - 128 ) * (float)(100.0 / 128.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F457  STSO2FT2 = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float < -100.0 || TempData_float > 99.2 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  STSO2FT2 outside expected range (-100 to 99.2)\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F457  STSO2FT4 = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -100.0 || TempData_float > 99.2 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  STSO2FT4 outside expected range (-100 to 99.2)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid58Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)( pPid->Data[0] - 128 ) * (float)(100.0 / 128.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F458  LGSO2FT2 = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float < -100.0 || TempData_float > 99.2 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  LGSO2FT2 outside expected range (-100 to 99.2)\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( gVariablePIDSize == 2 )
	{
		TempData_float = (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F458  LGSO2FT4 = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -100.0 || TempData_float > 99.2 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  LGSO2FT4 outside expected range (-100 to 99.2)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid59Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = ( (pPid->Data[0] << 8) +
	                   pPid->Data[1] ) * 10;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F459  FRP      = %d kPa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE &&
	     gbHybrid != TRUE &&
	     TempData_long == 0 )  // test 5.10 & 10.13
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FRP should not be 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid5AData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F45A  APP_R    = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float > 40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  APP_R should be less than 40 %%\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid5BData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F45B  BAT_PWR  = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE &&
	     TempData_float == 0 )  // test 5.10 & 10.13
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  BAT_PWR should not be 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid5CData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 40;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F45C  EOT      = %d C\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_long  < -20 || TempData_long > 150 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EOT outside expected range (-20 to 150)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid5DData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)(((pPid->Data[0] << 8) +
	                           pPid->Data[1] ) - 26880 ) / 128;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F45D  FUEL_TIMING = %.2f\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float < -210 || TempData_float >= 302 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FUEL_TIMING outside expected range (-209 to 301)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid5EData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = ( (pPid->Data[0] << 8) +
	                    pPid->Data[1] ) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F45E  FUEL_RATE = %.2f L/h\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( gbHybrid != TRUE &&
			     TempData_float == 0.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  FUEL_RATE should not be 0 when engine running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		else // test 5.6
		{
			if ( TempData_float != 0.0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  FUEL_RATE should be 0 when engine is not running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid5FData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F45F  EMIS_SUP = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_long  < 0x0E || TempData_long > 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EMIS_SUP outside expected range ($0E to $10)\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid61Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F461  TQ_DD    = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPid62Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F462  TQ_ACT   = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( TempData_long <= 0 )
			{
				if ( !(TempData_long == 0 && gbHybrid == TRUE) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  TQ_ACT should be greater than 0 when egine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
		else if ( TempData_long < 0 )  // test 5.6
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TQ_ACT should not be less than 0 when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid63Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = (pPid->Data[0] << 8) +
	                 pPid->Data[1];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F463  TQ_REF   = %d Nm\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE &&
	     TempData_long <= 0 )  // test 5.10 & 10.13
	{
		if ( !(TempData_long == 0 && gbHybrid == TRUE) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TQ_REF should be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid64Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = pPid->Data[0] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F464  TQ_MAX1  = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_long <= 0 )
		{
			if ( !(TempData_long == 0 && gbHybrid == TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  TQ_MAX1 should be greater than 0\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}

	TempData_long = pPid->Data[1] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F464  TQ_MAX2  = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_long <= 0 )
		{
			if ( !(TempData_long == 0 && gbHybrid == TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  TQ_MAX2 should be greater than 0\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}

	TempData_long = pPid->Data[2] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F464  TQ_MAX3  = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_long <= 0 )
		{
			if ( !(TempData_long == 0 && gbHybrid == TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  TQ_MAX3 should be greater than 0\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}

	TempData_long = pPid->Data[3] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F464  TQ_MAX4  = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_long <= 0 )
		{
			if ( !(TempData_long == 0 && gbHybrid == TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  TQ_MAX4 should be greater than 0\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}

	TempData_long = pPid->Data[4] - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F464  TQ_MAX5  = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
	{
		if ( TempData_long <= 0 )
		{
			if ( !(TempData_long == 0 && gbHybrid == TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  TQ_MAX5 should be greater than 0\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid65Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F465  Auxiliary I/O Support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Auxiliary I/O Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PTO_STAT_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    N/D_STAT_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    N/G_STAT_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    GPL_STAT_SUP  = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    GEAR_RCMD_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Auxiliary I/O Support  No devices supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( gstUserInput.eFuelType == DIESEL &&
	     (gstUserInput.eComplianceType == US_OBDII ||
	      gstUserInput.eComplianceType == HD_OBD) &&
	     (pPid->Data[0] & 0x08) == 0 )
	{
		Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Auxiliary I/O Support Bit 3 (GPL_STAT_SUP) must be set for diesel vehicles\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0xE0) != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Auxiliary I/O Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F465  Auxiliary I/O Status = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );

	// Auxiliary I/O Status bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PTO_STAT  = %s\n",
	      (pPid->Data[1] & 0x01) ? "ON" : "OFF" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    N/D_STAT  = %s\n",
	      (pPid->Data[1] & 0x02) ? "DRIVE" : "NEUT" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    N/G_STAT  = %s\n",
	      (pPid->Data[1] & 0x04) ? "GEAR" : "NEUT" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    GPL_STAT  = %s\n",
	      (pPid->Data[1] & 0x08) ? "ON" : "OFF" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
      "                    GEAR_RCMD = $%02X (%s)\n",
      pPid->Data[1] >> 4,
      szGEAR[pPid->Data[1] >> 4] );
}


void VerifyPid66Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F466  MAF Sensor support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Mass Air Flow Sensor Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MAFA_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MAFB_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  MAF Sensor support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  MAF Sensor support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)( (pPid->Data[1] << 8) +
		                           pPid->Data[2] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F466  MAFA     = %.3f g/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE )  // NOT Test 10.2
		{
			if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
			{
				if ( TempData_float <= 0 )
				{
					if ( !(TempData_float == 0.0 && gbHybrid == TRUE) )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  MAFA should be greater than 0 when engine running\n",
						      GetEcuId ( EcuIdx ) );
					}
				}
			}
			else  // test 5.6
			{
				if ( TempData_float > 5 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  MAFA should be less than or equal to 5 when engine is not running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (float)( (pPid->Data[3] << 8) +
		                           pPid->Data[4] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F466  MAFB     = %.3f g/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE )  // NOT Test 10.2
		{
			if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
			{
				if ( TempData_float <= 0 )
				{
				if ( !(TempData_float == 0.0 && gbHybrid == TRUE) )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  MAFB should be greater than 0 when engine is running\n",
						      GetEcuId ( EcuIdx ) );
					}
				}
			}
			else  // test 5.6
			{
				if ( TempData_float > 5 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  MAFB should be less than or equal to 5 when engine is not running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}
}


void VerifyPid67Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F467  ECT Sensor support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Engine Coolant Temperature Sensor Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ECT1_SUP   = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ECT2_SUP   = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ECT Sensor support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ECT Sensor support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F467  ECT1     = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  ECT1 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[2] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F467  ECT2     = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  ECT2 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid68Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F468  IAT Sensor support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Intake Air Temperature Sensor Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAT11_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAT12_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAT13_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAT21_SUP  = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAT22_SUP  = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAT23_SUP  = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x3F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  IAT Sensor support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  IAT Sensor support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = ( pPid->Data[1] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F468  IAT11    = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  IAT11 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = ( pPid->Data[2] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F468  IAT12    = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  IAT12 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[3] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F468  IAT13    = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  IAT13 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = ( pPid->Data[4] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F468  IAT21    = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  IAT21 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_long = ( pPid->Data[5] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F468  IAT22    = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  IAT22 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x20) != 0 )
	{
		TempData_long =  (pPid->Data[6] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F468  IAT23    = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  IAT23 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid69Data ( BYTE EcuIdx, PID *pPid )
{
	float          Temp_EGR_CMD;
	float          Temp_EGR_ACT;


	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F469  EGR data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// EGR System Data Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_A_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_A_ERR_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_B_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_B_ERR_SUP = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x3F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGR data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGR data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Temp_EGR_CMD = TempData_float;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F469  EGR_A_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE )  // test 5.6
		{
			if ( TempData_float > 10 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGR_A_CMD should be less than or equal to 10 %% when engine is not running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		else  // test 5.10 & 10.13
		{
			if ( gstUserInput.eFuelType == DIESEL )
			{
				if ( TempData_float > 100 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_A_CMD should be less than or equal to 100 %% when engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
			else if ( gstUserInput.eFuelType == GASOLINE )
			{
				if ( gbHybrid == FALSE &&
				     TempData_float > 10 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_A_CMD should be less than or equal to 10 %% when engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( gbHybrid == TRUE &&
				          TempData_float > 50 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_A_CMD should be less than or equal to 50 %% when engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Temp_EGR_ACT = TempData_float;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F469  EGR_A_ACT = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (float)(pPid->Data[3] - 128 ) * (float)(100.0 / 128.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F469  EGR_A_ERR = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		// if EGR_CMD and EGR_ACT supported, check for proper EGR_ERR
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x01) != 0 && (pPid->Data[0] & 0x02) != 0 )
		{
			if ( Temp_EGR_CMD == 0 )
			{
				if ( Temp_EGR_ACT == 0 && TempData_float != 0 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_A_ERR should be 0%% when EGR_A_CMD == 0%% and EGR_A_ACT == 0%%\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( Temp_EGR_ACT > 0 && pPid->Data[3] != 0xFF )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_A_ERR should be 99.2%% when EGR_A_CMD == 0%% and EGR_A_ACT > 0%%\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
		Temp_EGR_CMD = TempData_float;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F469  EGR_B_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE)  // test 5.6
		{
			if ( TempData_float > 10 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGR_B_CMD should be less than or equal to 10 %% when engine is not running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		else  // test 5.10 & 10.13
		{
			if ( gstUserInput.eFuelType == DIESEL )
			{
				if ( TempData_float > 100 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_B_CMD should be less than or equal to 100 %% when engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
			else if ( gstUserInput.eFuelType == GASOLINE )
			{
				if ( gbHybrid == FALSE && TempData_float > 10 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_B_CMD should be less than or equal to 10 %% when engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( gbHybrid == TRUE && TempData_float > 50 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_B_CMD should be less than or equal to 50 %% when engine is running\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_float = (float)pPid->Data[5] * (float)(100.0 / 255.0);
		Temp_EGR_ACT = TempData_float;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F469  EGR_B_ACT = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x20) != 0 )
	{
		TempData_float = (float)( pPid->Data[6] - 128) * (float)(100.0 / 128.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F469  EGR_B_ERR = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		// if EGR_CMD and EGR_ACT supported, check for proper EGR_ERR
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x08) != 0 && (pPid->Data[0] & 0x10) != 0 )
		{
			if ( Temp_EGR_CMD == 0 )
			{
				if ( Temp_EGR_ACT == 0 && TempData_float != 0 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_B_ERR should be 0%% when EGR_B_CMD == 0%% and EGR_B_ACT == 0%%\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( Temp_EGR_ACT > 0 && pPid->Data[6] != 0xFF )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGR_B_ERR should be 99.2%% when EGR_B_CMD == 0%% and EGR_B_ACT > 0%%\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}
}


void VerifyPid6AData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F46A  IAF data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Intake Air Flow Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAF_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAF_A_REL_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAF_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IAF_B_REL_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  IAF data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  IAF data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46A  IAF_A_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46A  IAF_A_REL = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46A  IAF_B_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46A  IAF_B_REL = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid6BData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F46B  EGRT sensor support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  EGR Temperature Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTA_SUP    = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTC_SUP    = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTB_SUP    = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTD_SUP    = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTA_WR_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTC_WR_SUP = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTB_WR_SUP = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGRTD_WR_SUP = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0xFF) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGRT sensor support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that only one range bit is set for each sensor
	TempData_long = pPid->Data[0] >> 4;
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & TempData_long ) != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGRT sensor support  Both Normal and Wide Range supported for sensor(s)\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x11) != 0 )
	{
		if ( (pPid->Data[0] & 0x01) != 0 )
		{
			TempData_long = (pPid->Data[1]) - 40;
		}
		else
		{
			TempData_long = ((pPid->Data[1]) * 4) - 40;
		}

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46B  EGRT11   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE )  // NOT Test 10.2
		{
			if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
			{
				if ( (pPid->Data[0] & 0x01) != 0 &&
				     (TempData_long < -20 || TempData_long > 215) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT11 outside expected range (-20 to 215)\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( (pPid->Data[0] & 0x10) != 0 &&
				          (TempData_long < -20 || TempData_long > 500) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT11 outside expected range (-20 to 500)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
			else  // test 5.6
			{
				if ( TempData_long < -20 || TempData_long > 200 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT11 outside expected range (-20 to 200)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x22) != 0 )
	{
		if ( (pPid->Data[0] & 0x02) != 0 )
		{
			TempData_long = (pPid->Data[2]) - 40;
		}
		else
		{
			TempData_long = ((pPid->Data[2]) * 4) - 40;
		}

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46B  EGRT12   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE )  // NOT Test 10.2
		{
			if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
			{
				if ( (pPid->Data[0] & 0x02) != 0 &&
				     (TempData_long < -20 || TempData_long > 215) )
				{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGRT12 outside expected range (-20 to 215)\n",
				      GetEcuId ( EcuIdx ) );
				}
				else if ( (pPid->Data[0] & 0x20) != 0 &&
				          (TempData_long < -20 || TempData_long > 500) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT12 outside expected range (-20 to 500)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
			else  // test 5.6
			{
				if ( TempData_long < -20 || TempData_long > 200 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT12 outside expected range (-20 to 200)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x44) != 0 )
	{
		if ( (pPid->Data[0] & 0x04) != 0 )
		{
			TempData_long = (pPid->Data[3]) - 40;
		}
		else
		{
			TempData_long = ((pPid->Data[3]) * 4) - 40;
		}

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46B  EGRT21   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE )  // NOT Test 10.2
		{
			if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
			{
				if ( (pPid->Data[0] & 0x04) != 0 &&
				     (TempData_long < -20 || TempData_long > 215) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT21 outside expected range (-20 to 215)\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( (pPid->Data[0] & 0x40) != 0 &&
				          (TempData_long < -20 || TempData_long > 500) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT21 outside expected range (-20 to 500)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
			else  // test 5.6
			{
				if ( TempData_long < -20 || TempData_long > 200 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  EGRT21 outside expected range (-20 to 200)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}

	if ( (pPid->Data[0] & 0x88) != 0 )
	{
		if ( (pPid->Data[0] & 0x08) != 0 )
		{
			TempData_long = (pPid->Data[4]) - 40;
		}
		else
		{
			TempData_long = ((pPid->Data[4]) * 4) - 40;
		}

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46B  EGRT22   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE )  // NOT Test 10.2
		{
			if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
			{
				if ( (pPid->Data[0] & 0x08) != 0 &&
				     (TempData_long < -20 || TempData_long > 215) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT22 outside expected range (-20 to 215)\n",
					      GetEcuId ( EcuIdx ) );
				}
				else if ( (pPid->Data[0] & 0x80) != 0 &&
				          (TempData_long < -20 || TempData_long > 500) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT22 outside expected range (-20 to 500)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
			else  // test 5.6
			{
				if ( TempData_long < -20 || TempData_long > 200 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  EGRT22 outside expected range (-20 to 200)\n",
					      GetEcuId ( EcuIdx ) );
				}
			}
		}
	}
}


void VerifyPid6CData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F46C  TAC data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  EGR Temperature Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TAC_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TP_A_REL_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TAC_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TP_B_REL_SUP  = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TAC data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TAC data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46C  TAC_A_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46C  TP_A_REL  = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE &&
		     gstUserInput.eFuelType == GASOLINE &&
		     gbHybrid == FALSE &&
		     TempData_float > 50 )  // NOT test 10.2
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TP_A_REL should be less than or equal to 50 %% \n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46C  TAC_B_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46C  TP_B_REL  = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE &&
		     gstUserInput.eFuelType == GASOLINE &&
		     gbHybrid == FALSE &&
		     TempData_float > 50 )  // NOT Test 10.2
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TP_B_REL should be less than or equal to 50 %%\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid6DData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F46D  FRP data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Fuel Pressure Control Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRP_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRP_A_SUP     = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRT_A_SUP     = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRP_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRP_B_SUP     = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRT_B_SUP     = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x3F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FRP data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  FRP data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = ((pPid->Data[1] << 8) +
		                  pPid->Data[2] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46D  FRP_A_CMD = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = ((pPid->Data[3] << 8) +
		                  pPid->Data[4] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46D  FRP_A     = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = ( pPid->Data[5] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46D  FRT_A     = %5d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FRT_A outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = ((pPid->Data[6] << 8) +
		                  pPid->Data[7] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46D  FRP_B_CMD = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_long = ((pPid->Data[8] << 8) +
		                  pPid->Data[9] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46D  FRP_B     = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x20) != 0 )
	{
		TempData_long = pPid->Data[10] - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46D  FRT_B     = %5d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FRT_B outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid6EData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F46E  ICP system data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Injection Pressure Control Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ICP_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ICP_A_SUP     = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ICP_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ICP_B_SUP     = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ICP data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ICP data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = ((pPid->Data[1] << 8) +
		                  pPid->Data[2] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46E  ICP_A_CMD = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = ((pPid->Data[3] << 8) +
		                  pPid->Data[4] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46E  ICP_A     = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = ((pPid->Data[5] << 8) +
		                  pPid->Data[6] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46E  ICP_B_CMD = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = ((pPid->Data[7] << 8) +
		                  pPid->Data[8] ) * 10;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46E  ICP_B     = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPid6FData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F46F  TCA sensor support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Injection Pressure Control Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_CINP_SUP    = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCB_CINP_SUP    = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_CINP_WR_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_CINP_WR_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TCA sensor support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TCA sensor support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// TCA_CINP supported
	if ( (pPid->Data[0] & 0x05) != 0 )
	{
		TempData_long = pPid->Data[1];
		//if 8kPa/bit
		if ( (pPid->Data[0] & 0x04) != 0 )
		{
			TempData_long *= 8;
		}
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46F  TCA_CINP  = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// TCB_CINP supported
	if ( (pPid->Data[0] & 0x0A) != 0 )
	{
		TempData_long = pPid->Data[2];
		//if 8kPa/bit
		if ( (pPid->Data[0] & 0x08) != 0 )
		{
			TempData_long *= 8;
		}
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F46F  TCB_CINP  = %5d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPid70Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F470  BP data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Boost Pressure Control Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    BP_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    BP_A_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    BP_A_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    BP_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    BP_B_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    BP_B_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x3F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  BP data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  BP data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F470  BP_A_CMD  = %4.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F470  BP_A_ACT  = %4.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = ((pPid->Data[5] << 8) +
		                   pPid->Data[6] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F470  BP_B_CMD  = %4.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_float = ((pPid->Data[7] << 8) +
		                   pPid->Data[8] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F470  BP_B_ACT  = %4.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// bit 2 (0x04) BP_A Status and bit 5 (0x20) BP_B Status
	if ( (pPid->Data[0] & 0x24) != 0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F470  BP control status = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[9] );
		//  Boost Pressure Status bits
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    BP_A_STA = %s\n",
		      szCON_STATUS[(pPid->Data[0] & 0x03)] );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    BP_B_STA = %s\n",
		      szCON_STATUS[(pPid->Data[0] & 0x0C) >> 2] );

		// check that reserved bits are not set
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[9] & 0xF0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  BP control status  Reserved bits set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid71Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F471  VGT data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Variable Geometry Turbo Control Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VGT_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VGT_A_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VGT_A_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VGT_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VGT_B_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VGT_B_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x3F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  VGT data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  VGT data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F471  VGT_A_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F471  VGT_A_ACT = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F471  VGT_B_CMD = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F471  VGT_B_ACT = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// bit 2 (0x04) VGT_A Status and bit 5 (0x20) VGT_B Status
	if ( (pPid->Data[0] & 0x24) != 0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F471  VGT control status = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[5] );
		//  Boost Pressure Status bits
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    VGT_A_STA = %s\n",
		      szCON_STATUS[(pPid->Data[5] & 0x03)] );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    VGT_B_STA = %s\n",
		      szCON_STATUS[(pPid->Data[5] & 0x0C) >> 2] );

		// check that reserved bits are not set
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[5] & 0xF0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F471  VGT control status  Reserved bits set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid72Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F472  WG data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Wastegate Control Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    WG_A_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    WG_A_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    WG_B_CMD_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    WG_B_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  WG data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  WG data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F472  WG_A_CMD  = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F472  WG_A_ACT  = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F472  WG_B_CMD  = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F472  WG_B_ACT  = %2.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid73Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F473  EP data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Exhaust Pressure Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EP1_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EP2_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EP data support  No sensors supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EP data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = ( (pPid->Data[1] << 8) +
		                    pPid->Data[2] ) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F473  EP1      = %4.2f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ( (pPid->Data[3] << 8) +
		                    pPid->Data[4] ) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F473  EP2      = %4.2f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid74Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F474  TC_RPM data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Exhaust Pressure Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_RPM_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCB_RPM_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TC_RPM data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TC_RPM data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F474  TCA_RPM  = %d RPM\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F474  TCB_RPM  = %d RPM\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPid75Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F475  TC A Temp data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Turbocharger A Temperature Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_CINT_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_COUTT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_TINT_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCA_TOUTT_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TC A Temp data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TC A Temp data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = ( pPid->Data[1] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F475  TCA_CINT  = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCA_CINT outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = ( pPid->Data[2] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F475  TCA_COUTT = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCA_COUTT outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (((pPid->Data[3] << 8) +
		                    pPid->Data[4] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F475  TCA_TINT  = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -20 || TempData_float > 1000 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCA_TINT outside expected range (-20 to 1000)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (((pPid->Data[5] << 8) +
		                    pPid->Data[6] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F475  TCA_TOUTT = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -20 || TempData_float > 1000 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCA_TOUTT outside expected range (-20 to 1000)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid76Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F476  TC B Temp data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Turbocharger A Temperature Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCB_CINT_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCB_COUTT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCB_TINT_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    TCB_TOUTT_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TC B Temp data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  TC B Temp data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = ( pPid->Data[1] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F476  TCB_CINT  = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCB_CINT outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = ( pPid->Data[2] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F476  TCB_COUTT = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCB_COUTT outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = ( ( (pPid->Data[3] << 8) +
		                      pPid->Data[4] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F476  TCB_TINT  = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -20 || TempData_float > 1000 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCB_TINT outside expected range (-20 to 1000)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = ( ( (pPid->Data[5] << 8) +
		                      pPid->Data[6] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F476  TCB_TOUTT = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float < -20 || TempData_float > 1000 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  TCB_TOUTT outside expected range (-20 to 1000)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid77Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F477  CACT data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Charge Air Cooler Temperature Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CACT11_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CACT12_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CACT21_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CACT22_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CACT data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CACT data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = ( pPid->Data[1] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F477  CACT11   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CACT11 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = ( pPid->Data[2] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F477  CACT12   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CACT12 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = ( pPid->Data[3] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F477  CACT21   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CACT21 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = ( pPid->Data[4] ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F477  CACT22   = %3d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_long < -20 || TempData_long > 120 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CACT22 outside expected range (-20 to 120)\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPid78Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F478  EGT Bank 1 data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Exhaust Gas Temperature Bank 1 Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT11_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT12_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT13_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT14_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGT Bank 1 data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGT Bank 1 data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (((pPid->Data[1] << 8) +
		                    pPid->Data[2] ) * (float).1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F478  EGT11    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (((pPid->Data[3] << 8) +
		                    pPid->Data[4] ) * (float).1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F478  EGT12    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (((pPid->Data[5] << 8) +
		                    pPid->Data[6] ) * (float).1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F478  EGT13    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (((pPid->Data[7] << 8) +
		                    pPid->Data[8] ) * (float).1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F478  EGT14    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid79Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F479  EGT Bank 2 data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Exhaust Gas Temperature Bank 2 Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT21_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT22_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT23_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT24_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGT Bank 2 data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGT Bank 2 data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (((pPid->Data[1] << 8) +
		                    pPid->Data[2] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F479  EGT21    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (((pPid->Data[3] << 8) +
		                    pPid->Data[4] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F479  EGT22    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (((pPid->Data[5] << 8) +
		                    pPid->Data[6] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F479  EGT23    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (((pPid->Data[7] << 8) +
		                    pPid->Data[8] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F479  EGT24    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid7AData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F47A  PF Bank 1 data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Particulate Filter Bank 1 Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF1_DP_SUP   = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF1_INP_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF1_OUTP_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x07) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PF Bank 1 data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF8 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PF Bank 1 data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)((signed short)((pPid->Data[1] << 8) +
		                                         pPid->Data[2] )) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47A  PF1_DP   = %4.1f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4] ) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47A  PF1_INP  = %4.1f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = ((pPid->Data[5] << 8) +
		                   pPid->Data[6] ) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47A  PF1_OUTP = %4.1f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid7BData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F47B  PF Bank 2 data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Particulate Filter Bank 2 Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF2_DP_SUP   = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF2_INP_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF2_OUTP_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x07) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PF Bank 2 data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF8 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PF Bank 2 data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (float)((signed short)((pPid->Data[1] << 8) +
		                                         pPid->Data[2] )) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47B  PF2_DP   = %4.1f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4] ) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47B  PF2_INP  = %4.1f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = ((pPid->Data[5] << 8) +
		                   pPid->Data[6] ) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47B  PF2_OUTP = %4.1f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid7CData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F47C  DPF Temp data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Particulate Filter Temperature Support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF1_INT_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF1_OUTT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF2_INT_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF2_OUTT_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  DPF Temp data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  DPF Temp data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = (((pPid->Data[1] << 8) +
		                    pPid->Data[2] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47C  DPF1_INT  = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = (((pPid->Data[3] << 8) +
		                    pPid->Data[4] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47C  DPF1_OUTT = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (((pPid->Data[5] << 8) +
		                    pPid->Data[6] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47C  DPF2_INT  = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_float = (((pPid->Data[7] << 8) +
		                    pPid->Data[8] ) * (float)0.1 ) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F47C  DPF2_OUTT = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid7DData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F47D  NOx NTE control area status = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// NOx NTE control area status bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NNTE_IN  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NNTE_OUT = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NNTE_CAA = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NNTE_DEF = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx NTE control area status  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid7EData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F47E  PM NTE control area status = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// PM NTE control area status bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PNTE_IN  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PNTE_OUT = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PNTE_CAA = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PNTE_DEF = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PM NTE control area status  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid7FData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F47F  Run Time support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Engine Run Time support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    RUN_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IDLE_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PTO_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x07) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF8 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 24) +
	                    (pPid->Data[2] << 16) +
	                    (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F47F  RUN_TIME  = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F47F  RUN_TIME  = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F47F  IDLE_TIME = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F47F  IDLE_TIME = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[9] << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F47F  PTO_TIME  = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F47F  PTO_TIME  = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}
}


void VerifyPid81Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F481  Run Time for AECD #1-#5 support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Engine Run Time for AECD #1 - #5 support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD1_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD2_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD3_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD4_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD5_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #1-#5 support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xE0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #1-#5 support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 24) +
		                (pPid->Data[2] << 16) +
		                (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD1_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD1_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD1_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD1_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[9]  << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD2_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD2_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD2_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD2_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8) +
		                 pPid->Data[20];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD3_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD3_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8) +
		                 pPid->Data[24];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD3_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD3_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8) +
		                 pPid->Data[28];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD4_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD4_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8) +
		                 pPid->Data[32];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD4_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD4_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8) +
		                 pPid->Data[36];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD5_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD5_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[37] << 24) +
		                (pPid->Data[38] << 16) +
		                (pPid->Data[39] << 8) +
		                 pPid->Data[40];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD5_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F481  AECD5_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}
}


void VerifyPid82Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F482  Run Time for AECD #6-#10 support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Engine Run Time for AECD #6 - #10 support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD6_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD7_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD8_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD9_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD10_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #6-#10 support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xE0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #6-#10 support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 24) +
		                (pPid->Data[2] << 16) +
		                (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD6_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD6_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD6_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD6_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[9] << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD7_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD7_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD7_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD7_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8) +
		                 pPid->Data[20];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD8_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD8_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8) +
		                 pPid->Data[24];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD8_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD8_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8) +
		                 pPid->Data[28];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD9_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD9_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8) +
		                 pPid->Data[32];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD9_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD9_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8) +
		                 pPid->Data[36];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD10_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD10_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[37] << 24) +
		                (pPid->Data[38] << 16) +
		                (pPid->Data[39] << 8) +
		                 pPid->Data[40];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD10_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F482  AECD10_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}
}


void VerifyPid83Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F483  NOx Sensor Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  NOx Sensor Data support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX11_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX12_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX21_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX22_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX11_DAT = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX12_DAT = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX21_DAT = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX22_DAT = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Sensor Data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F483  NOX11    = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x10) != 0 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOX11 should report $FFFF when Byte A Bit 4 (NOX11_DAT) is set\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F483  NOX12    = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x20) != 0 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOX12 should report $FFFF when Byte A Bit 5 (NOX12_DAT) is set\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F483  NOX21    = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x40) != 0 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOX21 should report $FFFF when Byte A Bit 6 (NOX21_DAT) is set\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F483  NOX22    = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x80) != 0 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOX22 should report $FFFF when Byte A Bit 7 (NOX22_DAT) is set\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}
}


void VerifyPid84Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F484  MST      = %d C\n",
	      GetEcuId ( EcuIdx ),
	      ( pPid->Data[0] ) -40 );
}


void VerifyPid85Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F485  NOx Reagent data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  NOx Control System  support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REAG_RATE_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REAG_DEMD_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REAG_LVL_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NWI_TIME_SUP  = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Reagent data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Reagent data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2] ) * (float)0.005;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F485  REAG_RATE = %.3f L/h\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4] ) * (float)0.005;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F485  REAG_DEMD = %.3f L/h\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_float = (float)(pPid->Data[5]) * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F485  REAG_LVL  = %.3f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = (pPid->Data[6] << 24) +
		                (pPid->Data[7] << 16) +
		                (pPid->Data[8] << 8) +
		                 pPid->Data[9];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F485  NWI_TIME  = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F485  NWI_TIME  = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}
}


void VerifyPid86Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F486  PM data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Particulate Matter Sensor support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM11_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM21_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PM data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PM data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2] ) * (float)0.0125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F486  PM11     = %.3f mg/m3\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4] ) * (float)0.0125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F486  PM21     = %.3f mg/m3\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid87Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F487  MAP data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Intake Manifold Absolute Pressure support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MAP_A_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MAP_B_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  MAP data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  MAP data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F487  MAP_A    = %.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( (TempData_float == 0.0) && (gbHybrid != TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  MAP_A must be non-zero when engine is running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4] ) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F487  MAP_B    = %.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
		{
			if ( (TempData_float == 0.0) && (gbHybrid != TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  MAP_B must be non-zero when engine is running\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}


void VerifyPid88Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_SYSTEM = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  SCR inducement system actual state bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LEVEL_LOW          = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    INCORR_REAG        = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CONSUMP_DEVIATION  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_LEVEL          = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ACTIVE             = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0x70 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  SCR_INDUCE_SYSTEM State  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}


	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_SYSTEM_HIST12 = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );
	//  SCR inducement system state 10K history bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LEVEL_LOW1         = %s\n",
	      (pPid->Data[1] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    INCORR_REAG1       = %s\n",
	      (pPid->Data[1] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CONSUMP_DEVIATION1 = %s\n",
	      (pPid->Data[1] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_LEVEL1         = %s\n",
	      (pPid->Data[1] & 0x08) ? "YES" : "NO" );
	//  SCR inducement system state 20K history bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LEVEL_LOW2         = %s\n",
	      (pPid->Data[1] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    INCORR_REAG2       = %s\n",
	      (pPid->Data[1] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CONSUMP_DEVIATION2 = %s\n",
	      (pPid->Data[1] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_LEVEL2         = %s\n",
	      (pPid->Data[1] & 0x80) ? "YES" : "NO" );


	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_SYSTEM_HIST34 = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[2] );
	//  SCR inducement system state 30K history bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LEVEL_LOW3         = %s\n",
	      (pPid->Data[2] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    INCORR_REAG3       = %s\n",
	      (pPid->Data[2] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CONSUMP_DEVIATION3 = %s\n",
	      (pPid->Data[2] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_LEVEL3         = %s\n",
	      (pPid->Data[2] & 0x08) ? "YES" : "NO" );
	//  SCR inducement system state 40K history bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LEVEL_LOW4         = %s\n",
	      (pPid->Data[2] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    INCORR_REAG4       = %s\n",
	      (pPid->Data[2] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CONSUMP_DEVIATION4 = %s\n",
	      (pPid->Data[2] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_LEVEL4         = %s\n",
	      (pPid->Data[2] & 0x80) ? "YES" : "NO" );

	TempData_long = ( (pPid->Data[3] << 8) +
	                   pPid->Data[4] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_DIST_1N = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	TempData_long = ( (pPid->Data[5] << 8) +
	                   pPid->Data[6] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_DIST_1D = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	TempData_long = ( (pPid->Data[7] << 8) +
	                   pPid->Data[8] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_DIST_2N = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	TempData_long = ( (pPid->Data[9] << 8) +
	                   pPid->Data[10] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_DIST_3N = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	TempData_long = ( (pPid->Data[11] << 8) +
	                   pPid->Data[12] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F488  SCR_INDUCE_DIST_4N = %d km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPid89Data ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F489  Run Time for AECD #11-#15 support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Engine Run Time for AECD #11 - #15 support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD11_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD12_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD13_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD14_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD15_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #11-#15 support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xE0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #11-#15 support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 24) +
		                (pPid->Data[2] << 16) +
		                (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD11_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD11_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD11_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD11_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[9] << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD12_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD12_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD12_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD12_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8) +
		                 pPid->Data[20];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD13_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD13_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8) +
		                 pPid->Data[24];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD13_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD13_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8) +
		                 pPid->Data[28];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD14_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD14_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8) +
		                 pPid->Data[32];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD14_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD14_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8) +
		                 pPid->Data[36];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD15_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD15_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[37] << 24) +
		                (pPid->Data[38] << 16) +
		                (pPid->Data[39] << 8) +
		                 pPid->Data[40];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD15_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F489  AECD15_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}
}


void VerifyPid8AData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48A  Run Time for AECD #16-#20 support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Engine Run Time for AECD #16 - #20 support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD16_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD17_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD18_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD19_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD20_TIME_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #16-#20 support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xE0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Run Time for AECD #16-#20 support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( (pPid->Data[0] & 0x01) != 0 )
	{
		TempData_long = (pPid->Data[1] << 24) +
		                (pPid->Data[2] << 16) +
		                (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD16_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD16_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD16_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD16_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x02) != 0 )
	{
		TempData_long = (pPid->Data[9]  << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD17_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD17_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD17_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD17_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x04) != 0 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8) +
		                 pPid->Data[20];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD18_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD18_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8) +
		                 pPid->Data[24];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD18_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD18_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x08) != 0 )
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8) +
		                 pPid->Data[28];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD19_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD19_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8) +
		                 pPid->Data[32];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD19_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD19_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}

	if ( (pPid->Data[0] & 0x10) != 0 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8) +
		                 pPid->Data[36];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD20_TIME1 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD20_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}

		TempData_long = (pPid->Data[37] << 24) +
		                (pPid->Data[38] << 16) +
		                (pPid->Data[39] << 8) +
		                 pPid->Data[40];
		if ( TempData_long == -1 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD20_TIME2 = n.a.\n" );
		}
		else
		{
			GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F48A  AECD20_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long,
			      hours, mins, secs );
		}
	}
}


void VerifyPid8BData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48B  Aftertreatment support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Aftertreatment Status support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF_REGEN_STAT_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF_REGEN_TYPE_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX_ADS_REGEN_SUP  = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX_ADS_DESULF_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF_REGEN_PCT_SUP   = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF_REGEN_AVGT_SUP  = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PF_REGEN_AVGD_SUP  = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );

	// check that reserved bit is not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0x80 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Aftertreatment Status support reserved bit 7 set\n",
		      GetEcuId ( EcuIdx ) );
	}

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48B  Aftertreatment Status = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );
	// Diesel Aftertreatment Status bits
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PF_REGEN_STATUS = %s\n",
		      (pPid->Data[1] & 0x01) ? "IN PROGRESS" : "NOT IN PROGRESS" );
	}
	if ( pPid->Data[0] & 0x02 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PF_REGEN_TYPE   = %s\n",
		      (pPid->Data[1] & 0x02) ? "ACTIVE" : "PASSIVE" );
	}
	if ( pPid->Data[0] & 0x04 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    NOX_ADS_REGEN    = %s\n",
		      (pPid->Data[1] & 0x04) ? "IN PROGRESS" : "NOT IN PROGRESS" );
	}
	if ( pPid->Data[0] & 0x08 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    NOX_ADS_DESULF   = %s\n",
		      (pPid->Data[1] & 0x08) ? "IN PROGRESS" : "NOT IN PROGRESS" );
	}

	// check that reserved bits are not set
	if ( pPid->Data[1] & 0xF0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48B  Aftertreatment Status  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x10 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48B  PF_REGEN_PCT  = %.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      (float)pPid->Data[2] * (float)(100.0 / 255.0) );
	}

	if ( pPid->Data[0] & 0x20 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48B  PF_REGEN_AVGT = %d minutes\n",
		      GetEcuId ( EcuIdx ),
		      (pPid->Data[3] << 8) +
		      pPid->Data[4] );
	}

	if ( pPid->Data[0] & 0x40 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48B  PF_REGEN_AVGD = %d km\n",
		      GetEcuId ( EcuIdx ),
		      (pPid->Data[5] << 8) +
		      pPid->Data[6] );
	}
}


void VerifyPid8CData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48C  O2 Sensor (Wide Range) support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// O2 Sensor (Wide Range) support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S11_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S12_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S21_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S22_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA11_SUP  = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA12_SUP  = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA21_SUP  = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA22_SUP  = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// display associated values
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)(.001526);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  O2S11_PCT = %3.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)(.001526);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  O2S12_PCT = %3.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)(.001526);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  O2S21_PCT = %3.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)(.001526);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  O2S22_PCT = %3.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)(.000122);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  LAMBDA11  = %.3f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)(.000122);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  LAMBDA12  = %.3f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)(.000122);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  LAMBDA21  = %.3f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)(.000122);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48C  LAMBDA22  = %.3f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid8DData ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48D  TP_G     = %.1f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPid8EData ( BYTE EcuIdx, PID *pPid )
{
	TempData_long = (signed long)(pPid->Data[0]) - 125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48E  TQ_FR    = %d %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPid8FData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F48F  PM Sensor support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Particulate Matter (PM) Sensor Output support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM11_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM11_SUP     = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM21_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM21_SUP     = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PM Sensor Data support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}
	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PM Sensor Data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// PM Sensor Operating Status Bank 1 Sensor 1
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48F  PM11 Sensor status = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[1] );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PM11_ACTIVE = %s\n",
		      (pPid->Data[1] & 0x01) ? "YES" : "NO" );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PM11_REGEN  = %s\n",
		      (pPid->Data[1] & 0x02) ? "YES" : "NO" );

		// check that reserved bit is not set
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[1] & 0xFC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PM11 Sensor Operating Status  Reserved bits set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// PM Sensor Normalized Output Bank 1 Sensor 1
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((signed short)((pPid->Data[2] << 8) +
		                                         pPid->Data[3] )) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48F  PM11     = %3.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// PM Sensor Operating Status Bank 2 Sensor 1
	if ( pPid->Data[0] & 0x04 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48F  PM21 Sensor status = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[4] );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PM21_ACTIVE = %s\n",
		      (pPid->Data[4] & 0x01) ? "YES" : "NO" );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PM21_REGEN  = %s\n",
		      (pPid->Data[4] & 0x02) ? "YES" : "NO" );

		if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[4] & 0xFC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PM21 Sensor Operating Status  Reserved bits set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// PM Sensor Normalized Output Bank 2 Sensor 1
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((signed short)((pPid->Data[5] << 8) +
		                                         pPid->Data[6] )) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F48F  PM21     = %3.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid90Data ( BYTE EcuIdx, PID *pPid )
{
	// WWH-OBD Vehicle OBD System Information
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F490  WWH-OBD Vehicle OBD System Information = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MI_DISP_VOBD = $%02X\n",
	      pPid->Data[0] & 0x03 );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MI_MODE_VOBD = $%02X\n",
	      (pPid->Data[0] & 0x3C)>>2 );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    VOBD_RDY = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X    WWH-OBD Vehicle OBD System Information  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_long = (pPid->Data[1] << 8) +
	                 pPid->Data[2];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F490  VOBD_MI_TIME = %d hrs\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPid91Data ( BYTE EcuIdx, PID *pPid )
{
	// WWH-OBD Vehicle OBD System Information
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F491  WWH-OBD ECU OBD System Information = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MI_MODE_ECU = $%02X\n",
	      pPid->Data[0] & 0x0F );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  WWH-OBD ECU OBD System Information support  Reserved bits set\n",
	      GetEcuId ( EcuIdx ) );
	}

	TempData_long = (pPid->Data[1] << 8) +
	                 pPid->Data[2];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F491  OBD_MI_TIME = %d hrs\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	TempData_long = (pPid->Data[3] << 8) +
	                 pPid->Data[4];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F491  OBD_B1_TIME = %d hrs\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPid92Data ( BYTE EcuIdx, PID *pPid )
{
	// Fuel System Control Status (Diesel)
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F492  Fuel System Control Status support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Fuel System Status support bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FP1_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FIQ1_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FIT1_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IFB1_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FP2_CL_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FIQ2_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FIT2_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    IFB2_CL_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( (pPid->Data[0] & 0xFF) == 0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Fuel System Control Status support  No data supported\n" );
	}

	// Fuel System Status
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F492  FUELSYS  = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );
	// Fuel Pressure Control 1 Status
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FP1_CL  = %c\n",
		      (pPid->Data[1] & 0x01) ? '1' : '0' );
	}
	// Fuel Injection Quantity Control 1 Status
	if ( pPid->Data[0] & 0x02 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FIQ1_CL = %c\n",
		      (pPid->Data[1] & 0x02) ? '1' : '0' );
	}
	// Fuel Injection Timing Control 1 Status
	if ( pPid->Data[0] & 0x04 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FIT1_CL = %c\n",
		      (pPid->Data[1] & 0x04) ? '1' : '0' );
	}
	// Idle Fuel Balance/Contribution Control 1 Status
	if ( pPid->Data[0] & 0x08 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    IFB1_CL = %c\n",
		      (pPid->Data[1] & 0x08) ? '1' : '0' );
	}
	// Fuel Pressure Control 2 Status
	if ( pPid->Data[0] & 0x10 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FP2_CL  = %c\n",
		      (pPid->Data[1] & 0x10) ? '1' : '0' );
	}
	// Fuel Injection Quantity Control 2 Status
	if ( pPid->Data[0] & 0x20 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FIQ2_CL = %c\n",
		      (pPid->Data[1] & 0x20) ? '1' : '0' );
	}
	// Fuel Injection Timing Control 2 Status
	if ( pPid->Data[0] & 0x40 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FIT2_CL = %c\n",
		      (pPid->Data[1] & 0x40) ? '1' : '0' );
	}
	// Idle Fuel Balance/Contribution Control 2 Status
	if ( pPid->Data[0] & 0x80 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    IFB2_CL = %c\n",
		      (pPid->Data[1] & 0x80) ? '1' : '0' );
	}
}


void VerifyPid93Data ( BYTE EcuIdx, PID *pPid )
{
	// WWH-OBD Vehicle OBD Counters support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F493  WWH-OBD Vehicle OBD Counters support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  WWH-OBD Vehicle Counters support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    MI_TIME_CUM_SUP = %s\n",
	      (pPid->Data[1] & 0x01) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  WWH-OBD Vehicle OBD Counters support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F493  MI_TIME_CUM = %d hrs\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPid94Data ( BYTE EcuIdx, PID *pPid )
{
	// NOx Warning And Inducement System support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F494  NOx Warning And Inducement System support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  NOx control - driver inducement system support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX_WARN_ACT_STA_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REAG_QUAL_TIME_SUP   = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REAG_CON_TIME_SUP    = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REAG_DOSE_TIME_SUP   = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_TIME_SUP         = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX_DTC_TIME_SUP     = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x3F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Warning And Inducement System support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Warning And Inducement System support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// NOx Warning And Inducement System support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F494  NOx Warning And Inducement System status  = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[1] );
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    NOX_WARN_ACT = %s\n",
		      (pPid->Data[1] & 0x01) ? "YES" : "NO" );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    INDUC_L1     = $%02X\n",
		      (pPid->Data[1] & 0x06)>>1 );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    INDUC_L2     = $%02X\n",
		      (pPid->Data[1] & 0x18)>>3 );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    INDUC_L3     = $%02X\n",
		      (pPid->Data[1] & 0x60)>>5 );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x80 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X    NOx Warning And Inducement Ststem status  Reserved bits set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	TempData_long = (pPid->Data[2] << 8) +
	                 pPid->Data[3];
	if ( pPid->Data[0] & 0x02 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F494  REAG_QUAL_TIME = %d hrs\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          TempData_long != 65535 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  REAG_QUAL_TIME must be 65535 if it is not supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_long = (pPid->Data[4] << 8) +
	                 pPid->Data[5];
	if ( pPid->Data[0] & 0x04 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F494  REAG_CON_TIME  = %d hrs\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          TempData_long != 65535 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  REAG_CON_TIME must be 65535 if it is not supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_long = (pPid->Data[6] << 8) +
	                 pPid->Data[7];
	if ( pPid->Data[0] & 0x08 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F494  REAG_DOSE_TIME = %d hrs\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          TempData_long != 65535 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  REAG_DOSE_TIME must be 65535 if it is not supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_long = (pPid->Data[8] << 8) +
	                 pPid->Data[9];
	if ( pPid->Data[0] & 0x10 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F494  EGR_TIME       = %d hrs\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          TempData_long != 65535 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGR_TIME must be 65535 if it is not supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_long = (pPid->Data[10] << 8) +
	                 pPid->Data[11];
	if ( pPid->Data[0] & 0x20 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F494  NOX_DTC_TIME   = %d hrs\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          TempData_long != 65535 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOX_DTC_TIME must be 65535 if it is not supported\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid95Data ( BYTE EcuIdx, PID *pPid )
{
	// SCR Catalyst NH3 Storage data support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F495  SCR Catalyst NH3 Storage data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  SCR Catalyst NH3 Storage data support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SCR_NH3_TGT_A_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SCR_NH3_ACT_A_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SCR_NH3_TGT_B_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SCR_NH3_ACT_B_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  SCR Catalyst NH3 Storage data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2]) * (float)(.0001);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $95  SCR_NH3_TGT_A = %f g/l\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4]) * (float) (.0001);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $95  SCR_NH3_ACT_A = %f g/l\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = ((pPid->Data[5] << 8) +
		                   pPid->Data[6]) * (float) (.0001);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $95  SCR_NH3_TGT_B = %f g/l\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = ((pPid->Data[7] << 8) +
		                   pPid->Data[8]) * (float) (.0001);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $95  SCR_NH3_ACT_B = %f g/l\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid96Data ( BYTE EcuIdx, PID *pPid )
{
	// Hydrocarbon Doser data support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F496  Hydrocarbon Doser data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  Hydrocarbon Doser data support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HC_INJ_F_SUP  = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HC_INJ_DC_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AFT_FP_SUP    = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF8 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Hydrocarbon Doser data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2]) * (float) (.05);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $96  HC_INJ_F = %f g/min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)(pPid->Data[3]) * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $96  HC_INJ_DC = %.3f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = ((pPid->Data[4] << 8) +
		                   pPid->Data[5]) * (float) (.1);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $96  AFT_FP = %f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid97Data ( BYTE EcuIdx, PID *pPid )
{
	// NOx Mass Emission Rate data support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F497  NOx Mass Emission Rate data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	//  NOx Mass Emission Rate data support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_EO   = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOx_TP   = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Mass Emission Rate data support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = ((pPid->Data[1] << 8) +
		                   pPid->Data[2]) * (float) (.0001);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $97  NOx_EO = %f g/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = ((pPid->Data[3] << 8) +
		                   pPid->Data[4]) * (float) (.0001);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $97  NOx_TP = %f g/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid98Data ( BYTE EcuIdx, PID *pPid )
{
	// Exhaust Gas Temperature Sensor support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F498  Exhaust Gas Temperature Sensor Bank 1 support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Exhaust Gas Temperature Sensor support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT15_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT16_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT17_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT18_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Exhaust Gas Temperature Sensor Bank 1 support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Exhaust Gas Temperature Sensor Bank 1 support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = ((float)((pPid->Data[1] << 8) +
		                           pPid->Data[2]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F498  EGT15    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = ((float)((pPid->Data[3] << 8) +
		                           pPid->Data[4]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F498  EGT16    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = ((float)((pPid->Data[5] << 8) +
		                           pPid->Data[6]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F498  EGT17    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = ((float)((pPid->Data[7] << 8) +
		                           pPid->Data[8]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F498  EGT18    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid99Data ( BYTE EcuIdx, PID *pPid )
{
	// Exhaust Gas Temperature Sensor support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F499  Exhaust Gas Temperature Sensor Bank 2 support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Exhaust Gas Temperature Sensor support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT25_SUP = %s\n",
	      (pPid->Data[0 & 0x01]) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT26_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT27_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGT28_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Exhaust Gas Temperature Sensor Bank 2 support  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Exhaust Gas Temperature Sensor Bank 2 support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = ((float)((pPid->Data[1] << 8) +
		                           pPid->Data[2]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F499  EGT25    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = ((float)((pPid->Data[3] << 8) +
		                           pPid->Data[4]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F499  EGT26    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = ((float)((pPid->Data[5] << 8) +
		                           pPid->Data[6]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F499  EGT27    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = ((float)((pPid->Data[7] << 8) +
		                           pPid->Data[8]) * (float).1) - (float)40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F499  EGT28    = %3.1f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid9AData ( BYTE EcuIdx, PID *pPid )
{
	// Hybrid/EV Vehicle System Data support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49A  Hybrid/EV Vehicle System Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Hybrid/EV Vehicle System Data support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_MODE_SUP     = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_V_SUP   = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_A_SUP   = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_MODE_ENH_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  Hybrid/EV Vehicle System Data support  Reserved bits set\n",
	      GetEcuId ( EcuIdx ) );
	}

	// Hybrid/EV Vehicle state
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49A  HEV_MODE     = %s\n",
		      GetEcuId ( EcuIdx ),
		      (pPid->Data[1] & 0x01) ? "CDM" : "CSM" );
	}

	// Enhanced Hybrid/EV Vehicle state
	if ( pPid->Data[0] & 0x08 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49A  ENH_HEV_MODE = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      (pPid->Data[1] & 0x06)>>1 );

		// Check if reserved bits set
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[1] & 0xF8 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HEV_MODE (Hybrid/EV Vehicle Charging state)  Reserved bits set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Hybrid/EV Battery System Voltage
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
		                                           pPid->Data[3] )) * (float)0.015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49A  HEV_BATT_V   = %.6f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     TempData_float <= 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HEV_BATT_V must be greater than 0 V\n",
			      GetEcuId ( EcuIdx ),
			      TempData_float );
		}
	}

	// Hybrid/EV Battery System Current
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((signed short)((pPid->Data[4] << 8) +
		                                         pPid->Data[5] )) * (float)0.1;

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49A  HEV_BATT_A   = %.1f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid9BData ( BYTE EcuIdx, PID *pPid )
{
	// Diesel Exhaust Fluid Sensor Data support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49B  Diesel Exhaust Fluid Sensor Data support = $%1X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] & 0x0F );
	// Diesel Exhaust Fluid Sensor Data support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_TYPE_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_CON_SUP  = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_T_SUP    = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_LVL_SUP  = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x07) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  Diesel Exhaust Fluid Sensor Data support  No data supported\n",
	      GetEcuId ( EcuIdx ) );
	}

	// Diesel Exhaust Fluid Type
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49B  DEF_TYPE = $%1X\n",
		      GetEcuId ( EcuIdx ),
		      (pPid->Data[0] >> 4) );
	}

	// Diesel Exhaust Fluid Concentration
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[1])) * (float)0.25;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49B  DEF_CON  = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Diesel Exhaust Fluid Tank Temperature
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[2])) - (float)40.00;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49B  DEF_T    = %f C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Diesel Exhaust Fluid Tank Level
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[3])) * (float)(100.0/255.0);

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49B  DEF_LVL  = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid9CData ( BYTE EcuIdx, PID *pPid )
{
	// Exhaust Gas Temperature Sensor support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49C  O2 Sensor Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Exhaust Gas Temperature Sensor support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S13_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S14_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S23_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S24_PCT_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA13_SUP  = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA14_SUP  = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA23_SUP  = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA24_SUP  = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0xFF) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  O2 Sensor Data support  No data supported\n",
	      GetEcuId ( EcuIdx ) );
	}

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float).001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  O2S13_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float).001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  O2S14_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float).001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  O2S23_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float).001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  O2S24_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float).000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  LAMBDA13  = %.6f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float).000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  LAMBDA14  = %.6f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float).000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  LAMBDA23  = %.6f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float).000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49C  LAMBDA24  = %.6f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPid9DData ( BYTE EcuIdx, PID *pPid )
{
	// Engine Fuel Rate
	TempData_float = (float)((unsigned short)((pPid->Data[0] << 8) +
	                                           pPid->Data[1])) * (float).02;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49D  ENG_FUEL_RATE = %.2f g/s\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     gbEngineRunning == FALSE && TempData_float != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ENG_FUEL_RATE must be 0 g/s when engine is not running\n",
		      GetEcuId ( EcuIdx ) );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          gbEngineRunning == TRUE && TempData_float == 0 &&
	          gbHybrid != TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ENG_FUEL_RATE must be greater than 0 g/s when engine is running\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
	                                           pPid->Data[3])) * (float).02;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49D  VEH_FUEL_RATE = %.2f g/s\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     gbEngineRunning == FALSE && TempData_float != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  VEH_FUEL_RATE must be 0 g/s when engine is not running\n",
		      GetEcuId ( EcuIdx ) );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          gbEngineRunning == TRUE && TempData_float == 0 &&
	          gbHybrid != TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  VEH_FUEL_RATE must be greater than 0 g/s when engine is running\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid9EData ( BYTE EcuIdx, PID *pPid )
{
	// Engine Exhaust Flow Rate
	TempData_float = (float)((unsigned short)((pPid->Data[0] << 8) +
	                                           pPid->Data[1])) * (float).2;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49E  EXH_RATE = %.2f kg/h\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     gbEngineRunning == FALSE && TempData_float != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EXH_RATE must be 0 kg/h when engine is not running\n",
		      GetEcuId ( EcuIdx ) );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          gbEngineRunning == TRUE && TempData_float == 0 &&
	          gbHybrid != TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EXH_RATE must be greater than 0 kg/h when engine is running\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPid9FData ( BYTE EcuIdx, PID *pPid )
{
	BOOL          bPid9FSuccess = FALSE;


	// Fuel System Percentage Use support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F49F  Fuel System Percentage Use support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Fuel System Percentage Use support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSA_B1_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSB_B1_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSA_B2_SUP = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSB_B2_SUP = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSA_B3_SUP = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSB_B3_SUP = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSA_B4_SUP = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYSB_B4_SUP = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0 &&  // bits 0,1  Fuel System A,B uses Bank 1
	     (pPid->Data[0] & 0x0C) == 0 &&  // bits 2,3  Fuel System A,B uses Bank 2
	     (pPid->Data[0] & 0x30) == 0 &&  // bits 4,5  Fuel System A,B uses Bank 3
	     (pPid->Data[0] & 0xC0) == 0 )   // bits 6,7  Fuel System A,B uses Bank 4
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Fuel System Percentage Use support  (At least one bank must be supported)\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[1]) * (float)(100.0/255.0));
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSA_B1 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSA_B1 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		            gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[2])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSB_B1 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSB_B1 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[3])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSA_B2 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSA_B2 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[4])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSB_B2 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSB_B2 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[5])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSA_B3 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSA_B3 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[6])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSB_B3 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSB_B3 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[7])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSA_B4 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSA_B4 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[8])) * (float)(100.0/255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F49F  FUELSYSB_B4 = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     gbEngineRunning == FALSE && TempData_float != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUELSYSB_B4 must be 0 %% when engine is not running\n",
			      GetEcuId ( EcuIdx ) );
		}
		else if ( gstUserInput.eComplianceType != US_ZEV &&
		          ((gbEngineRunning == TRUE && TempData_float != 0) ||
		           gbHybrid == TRUE) )
		{
			bPid9FSuccess = TRUE;
		}
	}

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     bPid9FSuccess == FALSE && gbEngineRunning == TRUE)
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  At least one of the FUELSYS banks must be greater than 0 %% when engine is running\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidA1Data ( BYTE EcuIdx, PID *pPid )
{
	// NOx Sensor Corrected Data support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A1  NOx Sensor Corrected Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// NOx Sensor Corrected Data support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC11_SUP       = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC12_SUP       = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC21_SUP       = %s\n",
	      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC22_SUP       = %s\n",
	      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC11_DAT_AVAIL = %s\n",
	      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC12_DAT_AVAIL = %s\n",
	      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC21_DAT_AVAIL = %s\n",
	      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC22_DAT_AVAIL = %s\n",
	      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NOx Sensor Corrected Data  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (unsigned short)((pPid->Data[1] << 8) +
		                                  pPid->Data[2]);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A1  NOXC11   = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x10) == 0x10 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOXC11 Data Availability Bit Set, Sensor Data should report $FFFF\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (unsigned short)((pPid->Data[3] << 8) +
		                                  pPid->Data[4]);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A1  NOXC12   = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x20) == 0x20 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOXC12 Data Availability Bit Set, Sensor Data should report $FFFF\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (unsigned short)((pPid->Data[5] << 8) +
		                                  pPid->Data[6]);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A1  NOXC21   = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x40) == 0x10 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOXC21 Data Availability Bit Set, Sensor Data should report $FFFF\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (unsigned short)((pPid->Data[7] << 8) +
		                                  pPid->Data[8]);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A1  NOXC22   = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		if ( gstUserInput.eComplianceType != US_ZEV &&
		     (pPid->Data[0] & 0x80) == 0x80 && TempData_long != 0xFFFF )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NOXC22 Data Availability Bit Set, Sensor Data should report $FFFF\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPidA2Data ( BYTE EcuIdx, PID *pPid )
{
	// Cylinder Fuel Rate
	TempData_float = (float)((unsigned short)((pPid->Data[0] << 8) +
	                                           pPid->Data[1])) * (float)0.03125;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A2  CYL_RATE = %.6f mg/stroke\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     gbEngineRunning == FALSE && TempData_float != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		     "ECU %X  CYL_RATE must be 0 mg/stroke when engine is not running\n",
		      GetEcuId ( EcuIdx ) );
	}
	else if ( gstUserInput.eComplianceType != US_ZEV &&
	          gbEngineRunning == TRUE && TempData_float == 0 &&
	          gbHybrid != TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CYL_RATE must be greater than 0 mg/stroke when engine is running\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidA3Data ( BYTE EcuIdx, PID *pPid )
{
// Evap System Vapor Pressure Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A3  Evaporative System Vapor Pressure support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Evap System Vapor Pressure Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_A_VP_SUP    = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_A_VP_WR_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_B_VP_SUP    = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_B_VP_WR_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((signed short)((pPid->Data[1] << 8) +
		                                         pPid->Data[2])) * (float)0.25;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A3  EVAP_A_VP = %.2f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (signed short)((pPid->Data[3] << 8) +
		                                 pPid->Data[4]) * 2;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $A3  EVAP_A_VP (Wide Range) = %d Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((signed short)((pPid->Data[5] << 8) +
		                                           pPid->Data[6])) * (float)0.25;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A3  EVAP_B_VP = %f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (signed short)((pPid->Data[7] << 8) +
		                                pPid->Data[8]) * 2;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $A3  EVAP_B_VP (Wide Range) = %d Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidA4Data ( BYTE EcuIdx, PID *pPid )
{
// Transmission Actual Gear Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A4  Transmission Actual Gear Status support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Transmission Actual Gear Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    GEAR_ACT_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    GEAR_RAT_SUP = %s\n",
	      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A4  GEAR_ACT = $%02X (%s)\n",
		      GetEcuId ( EcuIdx ),
		      (pPid->Data[1] >> 4),
		      szGEAR[(pPid->Data[1])>>4] );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
		                                           pPid->Data[3])) * (float)0.001;

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A4  GEAR_RAT = %.3f\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidA5Data ( BYTE EcuIdx, PID *pPid )
{
// Diesel Exhaust Fluid Dosing Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A5  Commanded DEF Dosing support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Diesel Exhaust Fluid Dosing Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_CMD_SUP  = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_UCDC_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((unsigned short)(pPid->Data[1])) * (float)0.5;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A5  DEF_CMD  = %3.1f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
		                                           pPid->Data[3])) * (float)0.0005;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A5  DEF_UCDC = %3.4f L\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidA6Data ( BYTE EcuIdx, PID *pPid )
{
	TempData_float = (float)((unsigned short)(pPid->Data[0] << 24) +
	                                         (pPid->Data[1] << 16) +
	                                         (pPid->Data[2] << 8) +
	                                          pPid->Data[3]) * (float)0.1;

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A6  ODO      = %.1f km (%.1f miles)\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float,
	      TempData_float/(float)1.609344 );
}



void VerifyPidA7Data ( BYTE EcuIdx, PID *pPid )
{
	// NOx Sensor Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A7  NOx Sensor Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// NOx Sensor Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX13_SUP       = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX14_SUP       = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX23_SUP       = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX24_SUP       = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX13_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX14_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX23_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOX24_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A7  NOX13 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x10 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A7  When NOX13_DAT_AVAIL is set NOX13 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A7  NOX14 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x20 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A7  When NOX14_DAT_AVAIL is set NOX14 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[5] << 8) +
		                 pPid->Data[6];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A7  NOX23 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x40 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A7  When NOX23_DAT_AVAIL is set NOX23 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( pPid->Data[0] & 0x08 && pPid->Data[0] & 0x80 )
	{
		TempData_long = (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A7  NOX24 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x80 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A7  When NOX24_DAT_AVAIL is set NOX24 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}
}


void VerifyPidA8Data ( BYTE EcuIdx, PID *pPid )
{
	// NOx Sensor Corrected Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A8  NOx Sensor Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// NOx Sensor Corrected Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC13_SUP       = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC14_SUP       = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC23_SUP       = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC24_SUP       = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC13_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC14_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC23_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NOXC24_DAT_AVAIL = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A8  NOXC13 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x10 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A8  When NOXC13_DAT_AVAIL is set NOXC13 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A8  NOXC14 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x20 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A8  When NOXC14_DAT_AVAIL is set NOXC14 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[5] << 8) +
		                 pPid->Data[6];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A8  NOXC23 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x40 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A8  When NOXC23_DAT_AVAIL is set NOXC23 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A8  NOXC24 = %d ppm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eComplianceType != US_ZEV &&
		     pPid->Data[0] & 0x80 && TempData_long != 65535 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4A8  When NOXC24_DAT_AVAIL is set NOXC24 must = 65535\n",
			      GetEcuId ( EcuIdx ),
			      TempData_long );
		}
	}
}


void VerifyPidA9Data ( BYTE EcuIdx, PID *pPid )
{
	// Motorcycle Input/Output Status Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4A9  Motorcycle Input/Output Status support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Motorcycle Input/Output Status Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    ABS_DISABLED_SUP = %s\n",
	      (pPid->Data[0] & 0x01) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4A9  ABS Disable Switch State = %02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[1] );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                  ABS_DISABLED = %s\n",
		      (pPid->Data[1] & 0x01) ? "YES" : "NO" );
	}
}


void VerifyPidAAData ( BYTE EcuIdx, PID *pPid )
{
	// Motorcycle Input/Output Status Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4AA  V_SET = %d km/h\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
}


void VerifyPidABData ( BYTE EcuIdx, PID *pPid )
{
	// Alternative Fuel Vehicle Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4AB  Alternative Fuel Vehicle Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Alternative Fuel Vehicle Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AFRP_AF_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FRT_AF_SUP  = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FTP_AF_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FTPW_AF_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FTT_AF_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.03125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AB  FRP_AF = %.5f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = pPid->Data[3] - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AB  FRT_AF = %.d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[4] << 8) +
		                          pPid->Data[5]) * (float)0.125;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AB  FTP_AF = %.3f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[6] << 8) +
		                 pPid->Data[7];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AB  FTPW_AF = %d kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = pPid->Data[8] - 256;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AB  FTT_AF = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidACData ( BYTE EcuIdx, PID *pPid )
{
	// Maximum DEF Dosing Rate/Mode Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4AC  Maximum DEF Dosing Rate/Mode support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Maximum DEF Dosing Rate/Mode Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_MODE_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_MAX_SUP  = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AC  DEF_MODE = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[1] );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[2] << 8) +
		                          pPid->Data[3]) * (float)0.3;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AC  DEF_MAX = %.1f g/hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidADData ( BYTE EcuIdx, PID *pPid )
{
	// Crankcase Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4AD  Crankcase Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Crankcase Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CKC_P_SUP         = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CKC_OSEP_RPM_SUP  = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CKCB_P_SUP        = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CKC_P_WR_SUP      = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CKCB_P_WR_SUP     = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );


	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Crankcase Data  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)((pPid->Data[0] & 0x08) ? 0.75 : 0.25);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AD  CKC_P = %.2f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AD  CKC_OSEP_RPM = %d rpm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)((pPid->Data[0] & 0x10) ? 0.75 : 0.25);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AD  CKCB_P = %.2f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidAEData ( BYTE EcuIdx, PID *pPid )
{
	// Evap System Purge Pressure Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4AE  Evap System Purge Pressure support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Crankcase Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_PP_SUP    = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_PP_WR_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.25;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AE  EVAP_PP = %.2f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = ((pPid->Data[3] << 8) +
		                  pPid->Data[4]) * 2;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4AE  EVAP_PP_WR = %d Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidAFData ( BYTE EcuIdx, PID *pPid )
{
	// Commanded/Target Fresh Air Flow
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1]) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4AF  AIR_FL_TGT = %.2f Pa\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPidB0Data ( BYTE EcuIdx, PID *pPid )
{
	// EGR Mass Flow data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B0  EGR Mass Flow data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// EGR Mass Flow data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_M_FL_A_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EGR_M_FL_B_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that required bit is set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EGR Mass Flow Data  No data supported\n",
		      GetEcuId ( EcuIdx ) );
	}


	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B0  EGR_M_FL_A = %.2f kg/hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B0  EGR_M_FL_B = %.2f kg/hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidB1Data ( BYTE EcuIdx, PID *pPid )
{
	// Diesel Fuel System Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B1  Diesel Fuel System support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Diesel Fuel System Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYS1_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FUELSYS2_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SHRTFT1_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LONGFT1_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SHRTFT2_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LONGFT2_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xC0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Diesel Fuel System Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Fuel System Status Bank 1
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B1  FUELSYS1 = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[1] );
		// Fuel system status Bank 1 Bits
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FUELSYS1_OL = %s\n",
		     (pPid->Data[1] & 0x01) ? "YES" : "NO" );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FUELSYS1_CL = %s\n",
		     (pPid->Data[1] & 0x02) ? "YES" : "NO" );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FUELSYS1_OL_Fault = %s\n",
		     (pPid->Data[1] & 0x04) ? "YES" : "NO" );
	}

	// Fuel System Status Bank 2
	if ( pPid->Data[0] & 0x02 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B1  FUELSYS2 = $%02X kg/hr\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[2] );
		// Fuel system status Bank 1 Bits
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FUELSYS2_OL = %s\n",
		     (pPid->Data[2] & 0x01) ? "YES" : "NO" );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FUELSYS2_CL = %s\n",
		     (pPid->Data[2] & 0x02) ? "YES" : "NO" );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    FUELSYS2_OL_Fault = %s\n",
		     (pPid->Data[2] & 0x04) ? "YES" : "NO" );
	}

	// Short Term Fuel Trim Bank 1
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[3] * 100) / 128) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B1  SHRTFT1 = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Long Term Fuel Trim Bank 1
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[4] * 100) / 128) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B1  LONGFT1 = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Short Term Fuel Trim Bank 2
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[5] * 100) / 128) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B1  SHRTFT2 = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Long Term Fuel Trim Bank 2
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[6] * 100) / 128) - (float)100.0;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B1  LONGFT2 = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidB2Data ( BYTE EcuIdx, PID *pPid )
{
	// Traction Battery Pack State of Health
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B2  BAT_SOH = %.2f %%\n",
	      GetEcuId ( EcuIdx ),
	      (float)pPid->Data[0] * (float)(100.0/255.0) );
}


void VerifyPidB3Data ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Actual Charge Rate Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B3  HVESP Actual Charge Rate support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Actual Charge Rate Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_ACR_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_ACR_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_ACR_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_ACR_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_ACR_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_ACR_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_ACR_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_ACR_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	//HVESS Actual charge rate
	TempData_float = (float)((pPid->Data[1] << 8) +
	                          pPid->Data[2]) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B3  HVESS_ACR = %f kW\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA Actual charge rate
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPA_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB Actual charge rate
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPB_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC Actual charge rate
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPC_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD Actual charge rate
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPD_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE Actual charge rate
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPE_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF Actual charge rate
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPF_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG Actual charge rate
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPG_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH Actual charge rate
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[17] << 8) +
		                          pPid->Data[18]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B3  HVESPH_ACR = %f kW\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidB4Data ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Temperature Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B4  HVESP Temperature support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Temperature Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_TEMP_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_TEMP_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	//HVESS Temperature
	TempData_long = (pPid->Data[1] << 8) +
	                 pPid->Data[2];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B4  HVESS_TEMP = %d C\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	// HVESPA Temperature
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPA_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPB Temperature
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[5] << 8) +
		                 pPid->Data[6];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPB_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPC Temperature
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPC_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPD Temperature
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[9] << 8) +
		                 pPid->Data[10];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPD_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPE Temperature
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPE_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPF Temperature
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_long = (pPid->Data[13] << 8) +
		                 pPid->Data[14];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPF_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPG Temperature
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_long = (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPG_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPH Temperature
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_long = (pPid->Data[17] << 8) +
		                 pPid->Data[18];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B4  HVESPH_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidB5Data ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Current Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B5  HVESP Current support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Current Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_CUR_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_CUR_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_CUR_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_CUR_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_CUR_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_CUR_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_CUR_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_CUR_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS Current
	TempData_float = (float)((pPid->Data[1] << 8) +
	                          pPid->Data[2]) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B5  HVESS_CUR = %f A\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA Current
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPA_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB Current
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPB_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC Current
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPC_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD Current
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPD_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE Current
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPE_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF Current
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPF_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG Current
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPG_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH Current
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[17] << 8) +
		                          pPid->Data[18]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B5  HVESPH_CUR = %f A\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidB6Data ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Voltage Level Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B6  HVESP Voltage Level support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Voltage Level Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_VOLT_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_VOLT_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_VOLT_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_VOLT_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_VOLT_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_VOLT_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_VOLT_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_VOLT_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS Voltage Level
	TempData_float = (float)((pPid->Data[1] << 8) +
	                          pPid->Data[2]) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B6  HVESS_VOLT = %f V\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA Voltage Level
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPA_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB Voltage Level
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPB_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC Voltage Level
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPC_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD Voltage Level
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPD_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE Voltage Level
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPE_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF Voltage Level
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPF_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG Voltage Level
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPG_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH Voltage Level
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[17] << 8) +
		                          pPid->Data[18]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B6  HVESPH_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidB7Data ( BYTE EcuIdx, PID *pPid )
{
	// Hybrid/EV Battery Temperature Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B7  Hybrid/EV Battery Temperature Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Hybrid/EV Battery Temperature Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_MIN_CELL_TEMP_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_MAX_CELL_TEMP_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_AVE_CELL_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_BUS_BAR_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_COOLANT_TEMP_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEV_BATT_THERM_MODE_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );


	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xC0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Hybrid/EV Battery Temperature Data Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Hybrid/EV Battery Min Cell Temperature
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = ((pPid->Data[1] << 8) +
		                  pPid->Data[2]) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B7  HEV_BATT_MIN_CELL_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Hybrid/EV Battery Max Cell Temperature
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = ((pPid->Data[3] << 8) +
		                  pPid->Data[4]) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B7  HEV_BATT_MAX_CELL_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Hybrid/EV Battery Average Cell Temperature
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = ((pPid->Data[5] << 8) +
		                  pPid->Data[6]) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B7  HEV_BATT_AVE_CELL_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Hybrid/EV Battery Bus Bar Temperature
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = ((pPid->Data[7] << 8) +
		                  pPid->Data[8]) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B7  HEV_BATT_BUS_BAR_TEMP_SUP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Hybrid/EV Battery Coolant Temperature
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = ((pPid->Data[9] << 8) +
		                  pPid->Data[10]) - 40;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B7  HEV_BATT_COOLANT_TEMP = %d C\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	//  Hybrid/EV Battery ESS Thermal Mode
	if ( pPid->Data[0] & 0x20 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4B7  HEV_BATT_THERM_MODE = %02X (%s)\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[11],
		      (pPid->Data[11] >= 0 && pPid->Data[11] <= 4) ? szHEV_BATT_THERM_MODE[pPid->Data[11]] : "RESERVED" );
	}
}


void VerifyPidB8Data ( BYTE EcuIdx, PID *pPid )
{
	// Hybrid/EV Battery High Voltage System Active Time Since Last Cell Balancing Complete
	TempData_long = (pPid->Data[1] << 8) +
	                 pPid->Data[2];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B8  HEV Batt Time Since Last Balance = %d min\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPidB9Data ( BYTE EcuIdx, PID *pPid )
{
	// Hybrid/EV Battery Min/Max Cell Voltage
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1]) * (float)0.001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B9  HEV_BAT_MIN_CELL_VOLTAGE = %.2f V\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
	if ( gbEngineRunning == TRUE &&  // test 5.10 and 12.5
	     TempData_float == 0.0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  HEV_BAT_MIN_CELL_VOLTAGE must be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}

	TempData_float = (float)((pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4B9  HEV_BAT_MAX_CELL_VOLTAGE = %.2f V\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
	if ( gbEngineRunning == TRUE &&  // test 5.10 and 12.5
	     TempData_float == 0.0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  HEV_BAT_MAX_CELL_VOLTAGE must be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidBAData ( BYTE EcuIdx, PID *pPid )
{
	// Hybrid/EV Battery Continuous Rated Power Available
	TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BA  HEV_BAT_PWR_AVAIL = %.2f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HEV Batt Charge Current Limit
	TempData_float = (float)((pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.1;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BA  HEV_BAT_CHARGE_CURRENT_LIMIT = %.1f A\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	TempData_float = (float)((pPid->Data[4] << 8) +
	                          pPid->Data[5]) * (float)0.1;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BA  HEV_BAT_DISCHARGE_CURRENT_LIMIT = %.1f A\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPidBBData ( BYTE EcuIdx, PID *pPid )
{
	// Cumulative energy into High Voltage Energy Storage Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BB  Cumulative energy into High Voltage Energy Storage Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Cumulative energy into High Voltage Energy Storage Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_ENRG_IN_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_ENRG_IN_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_ENRG_IN_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_ENRG_IN_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_ENRG_IN_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_ENRG_IN_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_ENRG_IN_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_ENRG_IN_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// Cumulative energy into High Voltage Energy Storage system
	TempData_long = (pPid->Data[1] << 24) +
	                (pPid->Data[2] << 16) +
	                (pPid->Data[3] << 8)  +
	                 pPid->Data[4];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BB  HVESS_ENRG_IN = %lu kWh\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	// Cumulative energy into High Voltage Energy Storage Pack A
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8)  +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPA_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack B
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[9]  << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8)  +
		                 pPid->Data[12];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPB_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack C
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8)  +
		                 pPid->Data[16];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPC_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack D
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8)  +
		                 pPid->Data[20];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPD_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack E
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8)  +
		                 pPid->Data[24];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPE_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack F
	if ( pPid->Data[0] & 0x20)
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8)  +
		                 pPid->Data[28];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPF_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack G
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8)  +
		                 pPid->Data[32];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPG_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy into High Voltage Energy Storage Pack H
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8)  +
		                 pPid->Data[36];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BB  HVESPH_ENRG_IN = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidBCData ( BYTE EcuIdx, PID *pPid )
{
	// Cumulative energy from High Voltage Energy Storage Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BC  Hybrid/EV Battery Temperature Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Cumulative energy from High Voltage Energy Storage Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_ENRG_OUT_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_ENRG_OUT_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_ENRG_OUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_ENRG_OUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_ENRG_OUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_ENRG_OUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_ENRG_OUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_ENRG_OUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// Cumulative energy from High Voltage Energy Storage system
	TempData_long = (pPid->Data[1] << 24) +
	                (pPid->Data[2] << 16) +
	                (pPid->Data[3] << 8)  +
	                 pPid->Data[4];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BC  HVESS_ENRG_OUT = %lu kWh\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	// Cumulative energy from High Voltage Energy Storage Pack A
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8)  +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPA_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack B
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[9]  << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8)  +
		                 pPid->Data[12];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPB_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack C
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8)  +
		                 pPid->Data[16];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPC_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack D
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8)  +
		                 pPid->Data[20];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPD_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack E
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8)  +
		                 pPid->Data[24];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPE_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack F
	if ( pPid->Data[0] & 0x20)
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8)  +
		                 pPid->Data[28];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPF_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack G
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8)  +
		                 pPid->Data[32];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPG_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Cumulative energy from High Voltage Energy Storage Pack H
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8)  +
		                 pPid->Data[36];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BC  HVESPH_ENRG_OUT = %lu kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidBDData ( BYTE EcuIdx, PID *pPid )
{
	// HVESS Total Energy Throughput Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BD  HVESS Total Energy Throughput Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESS Total Energy Throughput Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_ENRG_TPUT_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_ENRG_TPUT_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_ENRG_TPUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_ENRG_TPUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_ENRG_TPUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_ENRG_TPUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_ENRG_TPUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_ENRG_TPUT_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS Total Energy Throughput
	TempData_long = ((pPid->Data[1] << 24) +
	                 (pPid->Data[2] << 16) +
	                 (pPid->Data[3] << 8)  +
	                  pPid->Data[4]) * 100;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BD  HVESS_ENRG_TPUT = %lu Wh\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	// HVESPA Total Energy Throughput
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = ((pPid->Data[5] << 24) +
		                 (pPid->Data[6] << 16) +
		                 (pPid->Data[7] << 8)  +
		                  pPid->Data[8]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPA_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPB Total Energy Throughput
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = ((pPid->Data[9]  << 24) +
		                 (pPid->Data[10] << 16) +
		                 (pPid->Data[11] << 8)  +
		                  pPid->Data[12]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPB_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPC Total Energy Throughput
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = ((pPid->Data[13] << 24) +
		                 (pPid->Data[14] << 16) +
		                 (pPid->Data[15] << 8)  +
		                  pPid->Data[16]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPC_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPD Total Energy Throughput
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = ((pPid->Data[17] << 24) +
		                 (pPid->Data[18] << 16) +
		                 (pPid->Data[19] << 8)  +
		                  pPid->Data[20]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPD_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPE Total Energy Throughput
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = ((pPid->Data[21] << 24) +
		                 (pPid->Data[22] << 16) +
		                 (pPid->Data[23] << 8)  +
		                  pPid->Data[24]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPE_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPF Total Energy Throughput
	if ( pPid->Data[0] & 0x20)
	{
		TempData_long = ((pPid->Data[25] << 24) +
		                 (pPid->Data[26] << 16) +
		                 (pPid->Data[27] << 8)  +
		                  pPid->Data[28]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPF_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPG Total Energy Throughput
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_long = ((pPid->Data[29] << 24) +
		                 (pPid->Data[30] << 16) +
		                 (pPid->Data[31] << 8)  +
		                  pPid->Data[32]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPG_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// HVESPH Total Energy Throughput
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_long = ((pPid->Data[33] << 24) +
		                 (pPid->Data[34] << 16) +
		                 (pPid->Data[35] << 8)  +
		                  pPid->Data[36]) * 100;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BD  HVESPH_ENRG_TPUT = %lu Wh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidBEData ( BYTE EcuIdx, PID *pPid )
{
	// HVESS State of Health Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BE  HVESS State of Health support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESS State of Health Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_SOH_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_SOH_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_SOH_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_SOH_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_SOH_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_SOH_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_SOH_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_SOH_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS State of Health
	TempData_float = (float)pPid->Data[1] * (float)0.4;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BE  HVESS_SOH = %f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA State of Health
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)pPid->Data[2] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPA_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB State of Health
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)pPid->Data[3] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPB_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC State of Health
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)pPid->Data[4] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPC_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD State of Health
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)pPid->Data[5] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPD_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE State of Health
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)pPid->Data[6] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPE_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF State of Health
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)pPid->Data[7] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPF_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG State of Health
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)pPid->Data[8] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPG_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH State of Health
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)pPid->Data[9] * (float)0.4;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BE  HVESPH_SOH = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidBFData ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Recommended Minimum State Of Charge Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BF  HVESP Recommended Minimum State Of Charge support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Recommended Minimum State Of Charge Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_MIN_SOC_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_MIN_SOC_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_MIN_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_MIN_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_MIN_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_MIN_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_MIN_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_MIN_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS Recommended Minimum State Of Charge
	TempData_float = (float)((pPid->Data[1] << 8) +
	                          pPid->Data[2]) * (float)0.0015625;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BF  HVESS_MIN_SOC = %f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPA_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPB_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPC_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPD_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPE_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPF_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPG_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH Recommended Minimum State Of Charge
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[17] << 8) +
		                          pPid->Data[18]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4BF  HVESPH_MIN_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidC1Data ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Recommended Maximum State Of Charge Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C1  HVESP Recommended Maximum State Of Charge = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Recommended Maximum State Of Charge Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_MAX_SOC_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_MAX_SOC_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_MAX_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_MAX_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_MAX_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_MAX_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_MAX_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_MAX_SOC_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS Recommended Maximum State Of Charge
	TempData_float = (float)((pPid->Data[1] << 8) +
	                          pPid->Data[2]) * (float)0.0015625;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C1  HVESS_MAX_SOC = %f %%\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPA_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPB_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPC_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPD_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPE_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPF_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPG_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH Recommended Maximum State Of Charge
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[17] << 8) +
		                          pPid->Data[18]) * (float)0.0015625;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C1  HVESPH_MAX_SOC = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidC2Data ( BYTE EcuIdx, PID *pPid )
{
	// HVESP Discharge Energy Capacity Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C2  HVESP Discharge Energy Capacity = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// HVESP Discharge Energy Capacity Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPA_DENRG_CAP_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPB_DENRG_CAP_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPC_DENRG_CAP_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPD_DENRG_CAP_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPE_DENRG_CAP_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPF_DENRG_CAP_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPG_DENRG_CAP_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HVESPH_DENRG_CAP_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );


	// HVESS Discharge Energy Capacity
	TempData_float = (float)((pPid->Data[1] << 16) +
	                         (pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C2  HVESS_DENRG_CAP = %f kWh\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// HVESPA Discharge Energy Capacity
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[4] << 16) +
	                             (pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPA_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPB Discharge Energy Capacity
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[7] << 16) +
	                             (pPid->Data[8] << 8) +
		                          pPid->Data[9]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPB_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPC Discharge Energy Capacity
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[10] << 16) +
	                             (pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPC_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPD Discharge Energy Capacity
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[13] << 16) +
	                             (pPid->Data[14] << 8) +
		                          pPid->Data[15]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPD_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPE Discharge Energy Capacity
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[16] << 16) +
	                             (pPid->Data[17] << 8) +
		                          pPid->Data[18]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPE_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPF Discharge Energy Capacity
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[19] << 16) +
	                             (pPid->Data[20] << 8) +
		                          pPid->Data[21]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPF_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPG Discharge Energy Capacity
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_float = (float)((pPid->Data[22] << 16) +
	                             (pPid->Data[23] << 8) +
		                          pPid->Data[24]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPG_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// HVESPH Discharge Energy Capacity
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_float = (float)((pPid->Data[25] << 16) +
	                             (pPid->Data[26] << 8) +
		                          pPid->Data[27]) * (float)0.001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C2  HVESPH_DENRG_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidC3Data ( BYTE EcuIdx, PID *pPid )
{
	// Fuel Level Input Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C3  Fuel Level Input support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Fuel Level Input Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FLI_A_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FLI_B_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xFC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Fuel Level Input Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Fuel Level Input A
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C3  FLI_A = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Fuel Level Input B
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C3  FLI_B = %.2f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidC4Data ( BYTE EcuIdx, PID *pPid )
{
	// Exhaust Particulate Control System Diagnostic Time
	TempData_long = (pPid->Data[0] << 24) +
	                (pPid->Data[1] << 16) +
	                (pPid->Data[2] << 8)  +
	                 pPid->Data[3];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C4  EXH_PM_TIME = %lu sec\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	// Exhaust Particulate Control System Diagnostic Count
	TempData_long = (pPid->Data[4] << 24) +
	                (pPid->Data[5] << 16) +
	                (pPid->Data[6] << 8)  +
	                 pPid->Data[7];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4BB  EXH_PM_OCC_CNT = %lu\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPidC5Data ( BYTE EcuIdx, PID *pPid )
{
	// Fuel Level Input Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C5  Fuel Level Input support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Fuel Level Input Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LFP_A_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LFP_B_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xFC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Fuel Level Input Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Fuel Level Input A
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.079;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C5  FLI_A = %.2f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Fuel Level Input B
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.079;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C5  FLI_B = %.2f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidC6Data ( BYTE EcuIdx, PID *pPid )
{
	// Particulate warning and inducement systems Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C6  Particulate warning and inducement systems Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Particulate warning and inducement systems Data Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PM_WARN_ACT_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DPF_REMOVAL_BLOCKED_TIME_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LRIS_FAILURE_TIME_SUP  = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PCD_FAILURE_TIME_SUP  = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xF0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Particulate warning and inducement systems Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Particulate warning system activation status
	if ( pPid->Data[0] & 0x01 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C6  Particulate Warning System Status = %02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[1] );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    PM_WARN_ACT = %s\n",
		     (pPid->Data[1] & 0x01) ? "YES (Active)" : "NO (Inactive)" );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    INDUC_L1 = %d (Level one Inducement %s)\n",
		     (pPid->Data[1] >> 1) & 0x03,
		     szINDUC_L_STATUS[(pPid->Data[1] >> 1) & 0x03] );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    INDUC_L2 = %d (Level Two Inducement %s)\n",
		     (pPid->Data[1] >> 3) & 0x03,
		     szINDUC_L_STATUS[(pPid->Data[1] >> 3) & 0x03] );
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    INDUC_L2 = %d (Level Three Inducement %s)\n",
		     (pPid->Data[1] >> 5) & 0x03,
		     szINDUC_L_STATUS[(pPid->Data[1] >> 4) & 0x03] );

		// check that reserved bit is not set
		if ( pPid->Data[1] & 0x80 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Particulate Warning System Status  Reserved bit set\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Removal or block of the particulate aftertreatment system counter 
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[2] << 8) +
		                 pPid->Data[3];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C6  DPF_REMOVAL_BLOCKED_TIME = %lu hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Liquid reagent injection system (e.g. fuel-borne catalyst) failure counter 
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[4] << 8)  +
		                 pPid->Data[5];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C6  LRIS_FAILURE_TIME = %lu hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Malfunction of Particulate control monitoring system counter
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[6] << 8)  +
		                 pPid->Data[7];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C6  PCD_FAILURE_TIME = %lu hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidC7Data ( BYTE EcuIdx, PID *pPid )
{
	// Distance Since Reflash or Module Replacement
	TempData_long = (pPid->Data[0] << 8) +
	                 pPid->Data[1];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C7  REFLASH_DIST = %lu km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );
}


void VerifyPidC8Data ( BYTE EcuIdx, PID *pPid )
{
	// NOx Control Diagnostic (NCD) and Particulate Control Diagnostic (PCD) Warning Lamp status
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C7  NCD and PCD Warning Lamp status = %02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0]);
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NCD_PCD_WL = %d (NCD/PCD Warning Lamp %s)\n",
	     pPid->Data[1] & 0x03,
	     SZNCD_PCD_WARNING_LAMP_STATUS[(pPid->Data[1]) & 0x03] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    NCD_WL     = %d (NCD Warning Lamp %s)\n",
	     (pPid->Data[1] >> 2) & 0x03,
	     SZNCD_PCD_WARNING_LAMP_STATUS[(pPid->Data[1] >> 2) & 0x03] );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    PCD_WL     = %d (PCD Warning Lamp %s)\n",
	     (pPid->Data[1] >> 4) & 0x03,
	     szINDUC_L_STATUS[(pPid->Data[1] >> 4) & 0x03] );

	// check that reserved bit is not set
	if ( pPid->Data[1] & 0xC0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NCD and PCD Warning Lamp status  Reserved bit set\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidC9Data ( BYTE EcuIdx, PID *pPid )
{
	// O2 Sensor Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C9  O2 Sensor Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Diesel Fuel System Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S15_PCT_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S16_PCT_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S25_PCT     = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    O2S26_PCT     = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA15_SUP  = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA16_SUP  = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA25_SUP  = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    LAMBDA26_SUP  = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// O2 Sensor Concentration Bank 1 Sensor 5
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  O2S15_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Concentration Bank 1 Sensor 6
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  O2S16_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Concentration Bank 2 Sensor 5
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  O2S25_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Concentration Bank 2 Sensor 6
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[7] << 8) +
		                          pPid->Data[8]) * (float)0.001526;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  O2S26_PCT = %.6f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Lambda Bank 1 Sensor 5
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  LAMBDA15 = %.6f lambda\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Lambda Bank 1 Sensor 6
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_float = (float)((pPid->Data[11] << 8) +
		                          pPid->Data[12]) * (float)0.000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  LAMBDA16 = %.6f lambda\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Lambda Bank 2 Sensor 5
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[13] << 8) +
		                          pPid->Data[14]) * (float)0.000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  LAMBDA25 = %.6f lambda\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
	// O2 Sensor Lambda Bank 1 Sensor 5
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_float = (float)((pPid->Data[15] << 8) +
		                          pPid->Data[16]) * (float)0.000122;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4C9  LAMBDA26 = %.6f lambda\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidCAData ( BYTE EcuIdx, PID *pPid )
{
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4C9  is a RESERVED DID (DO NOT USE)\n",
	      GetEcuId ( EcuIdx ) );
}


void VerifyPidCBData ( BYTE EcuIdx, PID *pPid )
{
	// Exhaust Pressure Sensor Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4CB  Exhaust Pressure Sensor Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Diesel Fuel System Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EP_12_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EP_22_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that at least one sensor is supported
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x03) == 0x00 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CB  At least one sensor must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xFC )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CB  Exhaust Pressure Sensor Data  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// O2 Sensor Concentration Bank 1 Sensor 5
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CB  EP_12 = %.2f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// O2 Sensor Concentration Bank 1 Sensor 6
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.01;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CB  EP_22 = %.2f kPa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidCCData ( BYTE EcuIdx, PID *pPid )
{
	// Electric motor rpm Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4CC  Electric Motor RPM Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Electric motor rpm Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_A_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_B_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_C_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_D_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_E_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_F_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_G_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_H_RPM_SUP = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that at least one sensor is supported
	if ( pPid->Data[0] == 0x00 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  At least one must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// EMR Motor A motor rpm
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_A_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor B motor rpm
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_B_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor C motor rpm
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[5] << 8) +
		                 pPid->Data[6];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_C_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor D motor rpm
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_D_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor E motor rpm
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = (pPid->Data[9] << 8) +
		                 pPid->Data[10];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_E_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor F motor rpm
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_long = (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_F_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor G motor rpm
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_long = (pPid->Data[13] << 8) +
		                 pPid->Data[14];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_G_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor H motor rpm
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_long = (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CC  EM_H_RPM = %lu min\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidCDData ( BYTE EcuIdx, PID *pPid )
{
	// Electric motor Torque Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4CD  Electric Motor Torque Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Electric motor Torque Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_A_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_B_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_C_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_D_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_E_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_F_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_G_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EM_H_TQ_SUP = %s\n",
	     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

	// check that at least one sensor is supported
	if ( pPid->Data[0] == 0x00 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  At least one must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// EMR Motor A motor Torque
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_A_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor B motor Torque
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_B_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor C motor Torque
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[5] << 8) +
		                 pPid->Data[6];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_C_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor D motor Torque
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_D_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor E motor Torque
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = (pPid->Data[9] << 8) +
		                 pPid->Data[10];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_E_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor F motor Torque
	if ( pPid->Data[0] & 0x20 )
	{
		TempData_long = (pPid->Data[11] << 8) +
		                 pPid->Data[12];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_F_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor G motor Torque
	if ( pPid->Data[0] & 0x40 )
	{
		TempData_long = (pPid->Data[13] << 8) +
		                 pPid->Data[14];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_G_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// EMR Motor H motor Torque
	if ( pPid->Data[0] & 0x80 )
	{
		TempData_long = (pPid->Data[15] << 8) +
		                 pPid->Data[16];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CD  EM_H_TQ = %lu Nm\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidCEData ( BYTE EcuIdx, PID *pPid )
{
	// Evap System Vapor Pressure Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4CE  Evap System Vapor Pressure Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Evap System Vapor Pressure Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_C_VP_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_C_VP_WIDE_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_D_VP_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    EVAP_D_VP_WIDE_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that at least one sensor is supported
	if ( (pPid->Data[0] & 0x0F) == 0x00 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CE  At least one must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CE  Evap System Vapor Pressure Data  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Evap System Vapor Pressure C
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.25;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CE  EVAP_C_VP = %f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Evap System Vapor Pressure C (Wide Range)
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = ((pPid->Data[3] << 8) +
		                  pPid->Data[4]) * 2;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CE  EVAP_C_VP_WIDE = %lu Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Evap System Vapor Pressure D
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.25;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CE  EVAP_D_VP = %f Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Evap System Vapor Pressure D (Wide Range)
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = ((pPid->Data[7] << 8) +
		                  pPid->Data[8]) * 2;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CE  EVAP_D_VP_WIDE = %lu Pa\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidCFData ( BYTE EcuIdx, PID *pPid )
{
	// Catalyst Temperature Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4CF  Catalyst Temperature Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CATTEMPA_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CATTEMPB_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CATTEMPC_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    CATTEMPD_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that at least one sensor is supported
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0x00 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CF  At least one sensor must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CF  Catalyst Temperature Data  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Catalyst Temperature A
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CF  CATTEMPA = %d\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
		if ( gstUserInput.eFuelType == DIESEL &&
		     TempData_long == 0 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4CF  CATTEMPA must be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Catalyst Temperature B
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[3] << 8) +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CF  CATTEMPB = %d\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Catalyst Temperature C
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[5] << 8) +
		                 pPid->Data[6];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CF  CATTEMPC = %d\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Catalyst Temperature D
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[7] << 8) +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4CF  CATTEMPD = %d\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


void VerifyPidD0Data ( BYTE EcuIdx, PID *pPid )
{
	// Hybrid/EV Battery Capacity and Health Metrics Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D0  Hybrid/EV Battery Capacity and Health Metrics Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    HEALTH_DIST_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    REMAINING_ESS_RSRV_CAP_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    INIT_ESS_RSRV_CAP_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );

	// check that required bit are set
	if ( (pPid->Data[0] & 0x01) != 0x01 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D0  Hybrid/EV Battery Capacity and Health Metrics Data  Required bits not set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xF8 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D0  Hybrid/EV Battery Capacity and Health Metrics Data  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Distance Since Last SOH Update
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 8) +
		                 pPid->Data[2];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D0  HEALTH_DIST = %d km\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Remaining Energy Storage System Reserve Energy
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.1;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D0  REMAINING_ESS_RSRV_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// Initial Energy Storage System Reserve Energy
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.1;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D0  INIT_ESS_RSRV_CAP = %f kWh\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

}


void VerifyPidD1Data ( BYTE EcuIdx, PID *pPid )
{
	// Energy Storage System Actual Charging Limit
	TempData_float = (float)((pPid->Data[0] << 8) +
	                          pPid->Data[1]) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D1  HVESS_CHARGE_LIM = %f kW\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	// Energy Storage System Actual Charging Power
	TempData_float = (float)((pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.05;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D1  HVESS_CHARGE_ACT = %f kW\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPidD2Data ( BYTE EcuIdx, PID *pPid )
{
	// High Voltage Battery State of Certified Energy/Range Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D2  High Voltage Battery State of Certified Energy/Range Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SOCE_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    SOCR_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xFC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D2  High Voltage Battery State of Certified Energy/Range Data Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// State of certified energy
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D2  SOCE = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// State of certified range
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D2  SOCR = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidD3Data ( BYTE EcuIdx, PID *pPid )
{
	// Engine Odometer
	TempData_float = (float)((pPid->Data[0] << 24) +
	                         (pPid->Data[1] << 16) +
	                         (pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.1;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D3  ENGODO = %f km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gstUserInput.eComplianceType != US_ZEV &&
	     TempData_float == 0.0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D3  ENGODO must be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidD4Data ( BYTE EcuIdx, PID *pPid )
{
	// High Voltage Battery Pack Cumulative Energy During One Second
	TempData_float = (float)((pPid->Data[0] << 24) +
	                         (pPid->Data[1] << 16) +
	                         (pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.000001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D4  HVESS_ENER = %f Wh/s\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( gbEngineRunning == TRUE &&  // Test 12.5
	     TempData_float == 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D4  HVESS_ENER must be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidD5Data ( BYTE EcuIdx, PID *pPid )
{
	// Fuel Cell System Data Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D5  Fuel Cell System Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FC_VOLT_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FC_FUEL_RATE_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FC_CUMUL_CURR_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    FC_CUMUL_EMER_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xF0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D5  Fuel Cell System Data  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Fuel cell system voltage 
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)((pPid->Data[1] << 8) +
		                          pPid->Data[2]) * (float)0.05;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D5  FC_VOLT = %f V\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gbEngineRunning == TRUE &&  // Test 12.5
		     TempData_float == 0 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4D5  FC_VOLT must be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Fuel Cell Fuel Consumed During One Second 
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.0005;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D5  FC_FUEL_RATE = %f g/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gbEngineRunning == TRUE &&  // Test 12.5
		     TempData_float == 0.0 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4D5  FC_FUEL_RATE must be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Fuel Cell Cumulative Current During One Second
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[5] << 8) +
		                          pPid->Data[6]) * (float)0.02;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D5  FC_CUMUL_CURR = %f mAh/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gbEngineRunning == TRUE &&  // Test 12.5
		     TempData_float == 0.0 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4D5  FC_CUMUL_CURR must be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}

	// Fuel Cell Cumulative Energy During One Second
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_float = (float)((pPid->Data[7] << 24) +
		                         (pPid->Data[8] << 16) +
		                         (pPid->Data[9] << 8) +
		                          pPid->Data[10]) * (float)0.0001;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D5  FC_CUMUL_EMER = %f Wh/s\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );

		if ( gbEngineRunning == TRUE &&  // Test 12.5
		     TempData_float == 0.0 )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PID $F4D5  FC_CUMUL_EMER must be greater than 0\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
}


void VerifyPidD6Data ( BYTE EcuIdx, PID *pPid )
{
	// Number of propulsion system active trips since fault memory last cleared
	TempData_long = (pPid->Data[0] << 8) +
	                 pPid->Data[1];
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D6  NUMPSATRIPSFLTMEMCLR = %d\n",
	      GetEcuId ( EcuIdx ),
	      TempData_long );

	if ( geTestPhase == eTestZEV && gTestSubsection == 3 &&  // Test 12.3
	     TempData_long != 0.0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D6  NUMPSATRIPSFLTMEMCLR must be 0 after clear codes\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidD7Data ( BYTE EcuIdx, PID *pPid )
{
	// DEF Doser B
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D7  DEF Doser B Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_CMD_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_MODE_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    DEF_MAX_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );

	// check that at least one sensor is supported
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x0F) == 0x00 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D7  At least one sensor must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xF8 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D7  DEF Doser B Data Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// DEF_CMD
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_float = (float)(pPid->Data[1]) * (float)0.5;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D7  DEF_CMD = %f %%\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}

	// DEF_Mode
	if ( pPid->Data[0] & 0x02 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D7  DEF_MODE = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[2] );
	}

	// DEF_MAX
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_float = (float)((pPid->Data[3] << 8) +
		                          pPid->Data[4]) * (float)0.3;
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4D7  DEF_MAX = %f g/hr\n",
		      GetEcuId ( EcuIdx ),
		      TempData_float );
	}
}


void VerifyPidD8Data ( BYTE EcuIdx, PID *pPid )
{
	// Battery Capacity Calculation Ready
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D8  BCAP_R = %d (%s)\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0],
	      pPid->Data[0] == 1 ? "Ready" : "Not Ready" );
}


void VerifyPidD9Data ( BYTE EcuIdx, PID *pPid )
{
	// Calculated Energy Storage System Energy
	TempData_float = (float)((pPid->Data[0] << 24) +
	                         (pPid->Data[1] << 16) +
	                         (pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4D9  CALCULATED_ESS_CAP = %f kWh\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPidDAData ( BYTE EcuIdx, PID *pPid )
{
	// High Voltage Battery Pack Cumulative Current During One Second
	TempData_float = (float)((pPid->Data[0] << 24) +
	                         (pPid->Data[1] << 16) +
	                         (pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.000001;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4DA  HVESS_ENER = %f Ah/s\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );

	if ( geTestPhase == eTestZEV && gTestSubsection == 5 &&  // Test 12.5
	     TempData_float == 0.0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DA  HVESS_ENER must be greater than 0\n",
		      GetEcuId ( EcuIdx ) );
	}
}


void VerifyPidDBData ( BYTE EcuIdx, PID *pPid )
{
	// Energy Storage Total Odometer
	TempData_float = (float)((pPid->Data[0] << 24) +
	                         (pPid->Data[1] << 16) +
	                         (pPid->Data[2] << 8) +
	                          pPid->Data[3]) * (float)0.1;
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4DB  ESS_ODO = %f km\n",
	      GetEcuId ( EcuIdx ),
	      TempData_float );
}


void VerifyPidDCData ( BYTE EcuIdx, PID *pPid )
{
	// Run Time for AECD #21-#25 Support
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F4DC  Run Time for AECD #21-#25 Data support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );
	// Support Bits
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD21_TIME_SUP = %s\n",
	     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD22_TIME_SUP = %s\n",
	     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD23_TIME_SUP = %s\n",
	     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD24_TIME_SUP = %s\n",
	     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    AECD25_TIME_SUP = %s\n",
	     (pPid->Data[0] & 0x10) ? "YES" : "NO" );


	// check that at least one sensor is supported
	if ( gstUserInput.eComplianceType != US_ZEV &&
	     (pPid->Data[0] & 0x1F) == 0x00 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  At least one sensor must be supported\n",
		      GetEcuId ( EcuIdx ) );
	}

	// check that reserved bits are not set
	if ( pPid->Data[0] & 0xE0 )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  Run Time for AECD #21-#25 Data Support  Reserved bits set\n",
		      GetEcuId ( EcuIdx ) );
	}

	// Total run time with EI-AECD #21 Timer active
	if ( pPid->Data[0] & 0x01 )
	{
		TempData_long = (pPid->Data[1] << 24) +
		                (pPid->Data[2] << 16) +
		                (pPid->Data[3] << 8)  +
		                 pPid->Data[4];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD21_TIME1 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		TempData_long = (pPid->Data[5] << 24) +
		                (pPid->Data[6] << 16) +
		                (pPid->Data[7] << 8)  +
		                 pPid->Data[8];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD21_TIME2 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Total run time with EI-AECD #22 Timer active
	if ( pPid->Data[0] & 0x02 )
	{
		TempData_long = (pPid->Data[9]  << 24) +
		                (pPid->Data[10] << 16) +
		                (pPid->Data[11] << 8)  +
		                 pPid->Data[12];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD22_TIME1 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		TempData_long = (pPid->Data[13] << 24) +
		                (pPid->Data[14] << 16) +
		                (pPid->Data[15] << 8)  +
		                 pPid->Data[16];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD22_TIME2 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Total run time with EI-AECD #23 Timer active
	if ( pPid->Data[0] & 0x04 )
	{
		TempData_long = (pPid->Data[17] << 24) +
		                (pPid->Data[18] << 16) +
		                (pPid->Data[19] << 8)  +
		                 pPid->Data[20];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD23_TIME1 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		TempData_long = (pPid->Data[21] << 24) +
		                (pPid->Data[22] << 16) +
		                (pPid->Data[23] << 8)  +
		                 pPid->Data[24];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD23_TIME2 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Total run time with EI-AECD #24 Timer active
	if ( pPid->Data[0] & 0x08 )
	{
		TempData_long = (pPid->Data[25] << 24) +
		                (pPid->Data[26] << 16) +
		                (pPid->Data[27] << 8)  +
		                 pPid->Data[28];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD24_TIME1 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		TempData_long = (pPid->Data[29] << 24) +
		                (pPid->Data[30] << 16) +
		                (pPid->Data[31] << 8)  +
		                 pPid->Data[32];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD24_TIME2 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}

	// Total run time with EI-AECD #25 Timer active
	if ( pPid->Data[0] & 0x10 )
	{
		TempData_long = (pPid->Data[33] << 24) +
		                (pPid->Data[34] << 16) +
		                (pPid->Data[35] << 8)  +
		                 pPid->Data[36];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD25_TIME1 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );

		TempData_long = (pPid->Data[37] << 24) +
		                (pPid->Data[38] << 16) +
		                (pPid->Data[39] << 8)  +
		                 pPid->Data[40];
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F4DC  AECD25_TIME2 = %lu sec\n",
		      GetEcuId ( EcuIdx ),
		      TempData_long );
	}
}


STATUS VerifyPidF501Data ( BYTE EcuIdx, PID *pPid )
{
	BOOL bTestFailed = FALSE;
	
	
	// Capture the response from PID $F501
	// for use with MID verification logic
	memcpy ( &gstResponse[EcuIdx].PIDF501, &pPid[0], sizeof ( PID ) );

	DisplayPIDF501 ( EcuIdx );

	// Check if the MIL is ON (PID $F501 Data A Bit 7)
	if ( pPid->Data[0] & 0x80 )
	{
		if ( gbDTCStored == FALSE )
		{
			// MIL is ON when there should not be a stored DTC
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MIL status failure (MIL is ON when there should not be a stored DTC).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Check for DTC Count (PID $F501 Data A Bits 0-6)
	if ( pPid->Data[0] & 0x7F )
	{
		// If DTC status bit(s) set when there should not be a stored DTC
		if ( gbDTCStored == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  DTC Count failure (Non-zero when there should not be a stored DTC).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}


	// Evaluate Data B, BIT 0 - Misfire (MIS) support - must be 1 for at least one ECU for all engines
	if ( (pPid->Data[1] & 0x01) == 0x01 )
	{
		IMBitSupportFlags = IMBitSupportFlags | MIS_SUP;
	}

	// Evaluate Data B, BIT 1 - Fuel System (FUEL) support - must be 1 for at least one ECU for all engines
	if ( (pPid->Data[1] & 0x02) == 0x02 )
	{
		IMBitSupportFlags = IMBitSupportFlags | FUEL_SUP;
	}

	// Evaluate Data B, BIT 2 - Comprehensive Component (CCM) support - must be 1 for all ECUs for all engines
	if ( (pPid->Data[1] & 0x04) != 0x04 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CCM Monitor must be supported (CCM_SUP = 1) by all ECUs\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data B BIT 3 - Engine Cooling (COOL) support - must be 1 for at least one ECU for all engines
	if ( (pPid->Data[1] & 0x08) == 0x08 )
	{
		IMBitSupportFlags = IMBitSupportFlags | COOL_SUP;
	}

	// Evaluate Data B, BIT 4 - Misfire (MIS) status
	// if MIS is supported
	if ( (pPid->Data[1] & 0x01) == 0x01 )
	{
		// Bit 4 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		if ( (pPid->Data[1] & 0x10) != 0x00 &&
		     geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MIS Monitor must be complete (MIS_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
		}
	}
	// If monitor unsupported, it must indicate complete
	else if ( (pPid->Data[1] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported MIS Monitor (MIS_SUP = 0) must be complete (MIS_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data B, BIT 5 - Fuel System (FUEL) status
	// if FUEL is supported
	if ( (pPid->Data[1] & 0x02) == 0x02 )
	{
		// Bit 5 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		if ( (pPid->Data[1] & 0x20) != 0x00 &&
		     geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  FUEL Monitor must be complete (FUEL_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// If monitor unsupported, it must indicate complete
	else if ( (pPid->Data[1] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported FUEL Monitor (FUEL_SUP = 0) must be complete (FUEL_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data B, BIT 6 - Comprehensive Component (CCM) status
	// if CCM is supported
	if ( (pPid->Data[1] & 0x04) == 0x04 )
	{
		// Must be incomplete after Clear Codes (may complete during idle)
		if ( (pPid->Data[1] & 0x40) == 0x00 &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CCM Monitor must be incomplete (CCM_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 6 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[1] & 0x40) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CCM Monitor must be complete (CCM_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// If monitor unsupported, it must indicate complete
	else if ( (pPid->Data[1] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported CCM Monitor (CCM_SUP = 0) must be complete (CCM_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data B, BIT 7 - Engine Cooling (COOL) status
	// if COOL is supported
	if ( (pPid->Data[1] & 0x08) == 0x08 )
	{
		// Must be incomplete after Clear Codes (may complete during idle)
		if ( (pPid->Data[1] & 0x80) == 0x00 &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  COOL Monitor must be incomplete (COOL_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// If monitor unsupported, it must indicate complete
	else if ( (pPid->Data[1] & 0x80) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported COOL Monitor (COOL_SUP = 0) must be complete (COOL_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}


	// Evaluate Data C, BIT 0 - Catalyst (CAT) support - must be 1 for at least one ECU for Gasoline engines
	if ( (pPid->Data[2] & 0x01) == 0x01 )
	{
		IMBitSupportFlags = IMBitSupportFlags | CAT_SUP;

		if ( gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CAT Monitor supported (CAT_SUP = 1) (Must not be supported for Diesel vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data C, BIT 1 - Non-Methane Hydrocarbon Catalyst (HCCAT) support - must be 1 for at least one ECU for Diesel engines
	if ( (pPid->Data[2] & 0x02) == 0x02 )
	{
		IMBitSupportFlags = IMBitSupportFlags | HCCAT_SUP;

		if ( gstUserInput.eFuelType == GASOLINE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HCCAT Monitor supported (HCCATSUP = 1) (Must not be supported for Gasoline vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data C, BIT 2 - Heated Catalyst (HCAT) support
	if ( (pPid->Data[2] & 0x04) == 0x04 )
	{
		if ( gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HCAT Monitor supported (HCAT_SUP = 1) (Must not be supported for Diesel vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data C, BIT 3 - NOx Catalyst (NCAT) support - must be 1 for at least one ECU for Diesel engines
	if ( (pPid->Data[2] & 0x08) == 0x08 )
	{
		IMBitSupportFlags = IMBitSupportFlags | NCAT_SUP;

		if ( gstUserInput.eFuelType == GASOLINE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NCAT Monitor supported (NCAT_SUP = 1) (Must not be supported for Gasoline vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data C, BIT 4 - Catalys (CAT) status
	// Must be clear for Diesel vehicles
	if ( (pPid->Data[2] & 0x10) == 0x10 &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CAT Monitor incomplete (CAT_RDY = 1) (Must be complete (0) for Diesel vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if CAT is supported
	if ( (pPid->Data[2] & 0x01) == 0x01 )
	{
		// Must be incomplete after Clear Codes (may complete during idle)
		if ( (pPid->Data[2] & 0x10) == 0x00 &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CAT Monitor must be incomplete (CAT_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 4 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[2] & 0x10) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CAT Monitor must be complete (CAT_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[2] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported CAT Monitor (CAT_SUP = 0) must be complete (CAT_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data C, BIT 5 - Non-Methane Hydrocarbon Catalyst (HCCAT) status
	// Must be clear for Gasoline vehicles
	if ( (pPid->Data[2] & 0x20) == 0x20 &&
	     gstUserInput.eFuelType == GASOLINE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  HCCAT Monitor incomplete (HCCATRDY = 1) (Must be complete (0) for Gasoline vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if HCCAT is supported
	if ( (pPid->Data[2] & 0x02) == 0x02 )
	{
		// Must be incomplete after Clear Codes (may complete during idle)
		if ( (pPid->Data[2] & 0x20) == 0x00 &&
		      geTestPhase == eTestNoDTC &&
		      gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HCCAT Monitor must be incomplete (HCCAT_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 5 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[2] & 0x20) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HCCAT Monitor must be complete (HCCAT_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[2] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported HCCAT Monitor (HCCATSUP = 0) must be complete (HCCATRDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data C, BIT 6 - Heated Catalyst (HCAT) status
	// Must be clear for Diesel vehicles
	if ( (pPid->Data[2] & 0x40) == 0x40 &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  HCAT Monitor incomplete (HCAT_RDY = 1) (Must be complete (0) for Diesel vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if HCAT is supported
	if ( (pPid->Data[2] & 0x04) == 0x04 )
	{
		// Must be incomplete after Clear Codes (may complete during idle)
		if ( (pPid->Data[2] & 0x40) == 0x00 &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HCAT Monitor must be incomplete (HCAT_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 6 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[2] & 0x40) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  HCAT Monitor must be complete (HCAT_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[2] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported HCAT Monitor (HCAT_SUP = 0) must be complete (HCAT_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data C, BIT 7 - NOx Catalyst (NCAT) status
	// Must be clear for Gasoline vehicles
	if ( (pPid->Data[2] & 0x80) == 0x80 &&
	     gstUserInput.eFuelType == GASOLINE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NCAT Monitor incomplete (NCAT_RDY = 1) (Must be complete (0) for Gasoline vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if NCAT is supported
	if ( (pPid->Data[2] & 0x08) == 0x08 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[2] & 0x80) == 0x00 &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NCAT Monitor must be incomplete (NCAT_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 7 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[1] & 0x80) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NCAT Monitor must be complete (NCAT_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[2] & 0x80) == 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported NCAT Monitor (NCAT_SUP = 0) must be complete (NCAT_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}


	// Evaluate Data D, BIT 0 - Evaporative (EVAP) support - must be 1 for at least one ECU for Gasoline engines
	if ( (pPid->Data[3] & 0x01) == 0x01 )
	{
		IMBitSupportFlags = IMBitSupportFlags | EVAP_SUP;

		if ( gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EVAP monitor supported (EVAP_SUP = 1) (Must not be supported for Diesel vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data D, BIT 1 - Secondary Air (AIR) support
	if ( (pPid->Data[3] & 0x02) == 0x02 )
	{
		if ( gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  AIR Monitor supported (AIR_SUP = 1) (Must not be supported for Diesel vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data D, BIT 2 - Boost Pressure (BP) support
	if ( (pPid->Data[3] & 0x04) == 0x04 )
	{
		if ( gstUserInput.eFuelType == GASOLINE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  BP Monitor supported (BP_SUP = 1) (Must not be supported for Gasoline vehicles)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data D, BIT 3 - Particulate Matter Filter (PF) support - must be 1 for at least one ECU for Diesel engines or China6 Gasoline engines
	if ( (pPid->Data[3] & 0x08) == 0x08 )
	{
		IMBitSupportFlags = IMBitSupportFlags | PF_SUP;
	}


	// Evaluate Data D, BIT 4 - Evaporative (EVAP) status
	// Must be clear for Diesel vehicles
	if ( (pPid->Data[3] & 0x10) == 0x10 &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  EVAP Monitor incomplete (EVAP_RDY = 1) (Must be complete (0) for Diesel vehicles).\n",
		      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
	}
	// if EVAP is supported
	if ( (pPid->Data[3] & 0x01) == 0x01 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[3] & 0x10) == 0x00 &&
		     (gstUserInput.eComplianceType != EOBD && gstUserInput.eFuelType != GASOLINE) &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EVAP Monitor must be incomplete (EVAP_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 4 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[3] & 0x10) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EVAP Monitor must be complete (EVAP_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[3] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported EVAP Monitor (EVAP_SUP = 0) must be complete (EVAP_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data D, BIT 5 - Secondary Air (AIR) status
	// Must be clear for Diesel vehicles
	if ( (pPid->Data[3] & 0x20) == 0x20 &&
	     gstUserInput.eFuelType == DIESEL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  AIR Monitor incomplete (AIR_RDY = 1) (Must be complete (0) for Diesel vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if AIR is supported
	if ( (pPid->Data[3] & 0x02) == 0x02)
	{
		// Must be incomplete after Clear Codes (may complete during idle)
		if ( (pPid->Data[3] & 0x20) == 0x00 &&
		     geTestPhase == eTestNoDTC &&
		     gbEngineRunning == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  AIR Monitor must be incomplete (AIR_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 5 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[3] & 0x20) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  AIR Monitor must be complete (AIR_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[3] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported AIR Monitor (AIR_SUP = 0) must be complete (AIR_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data D, BIT 6 - Boost Pressure (BP) status
	// Must be clear for Gasoline vehicles
	if ( (pPid->Data[3] & 0x40) == 0x40 &&
	     gstUserInput.eFuelType == GASOLINE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  BP Monitor incomplete (BP_RDY = 1) (Must be complete (0) for Gasoline vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if BP is supported
	if ( (pPid->Data[3] & 0x04) == 0x04 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[3] & 0x40) == 0x00 &&
		     geTestPhase == eTestNoDTC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  BP Monitor must be incomplete (BP_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 6 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[3] & 0x40) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  BP Monitor must be complete (BP_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[3] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported BP Monitor (BP_SUP = 0) must be complete (BP_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data D, BIT 7 - Particulate Matter Filter (PF) status
	// if PF is supported
	if ( (pPid->Data[3] & 0x08) == 0x08 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[3] & 0x80) == 0x00 &&
		     geTestPhase == eTestNoDTC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PF Monitor must be incomplete (PF_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 7 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[3] & 0x80) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  PF Monitor must be complete (PF_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[3] & 0x80) == 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported PF Monitor (PF_SUP = 0) must be complete (PF_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}


	// Evaluate Data E, BIT 0 - Exhaust Gas Sensor (EGS) support - must be 1 for at least one ECU for all engines
	if ( (pPid->Data[4] & 0x01) == 0x01 )
	{
		IMBitSupportFlags = IMBitSupportFlags | EGS_SUP;
	}

	// Evaluate Data E, BIT 1 - Crankcase Ventilation (CV) support - must be 1 for at least one ECU for all engines
	if ( (pPid->Data[4] & 0x02) == 0x02 )
	{
		IMBitSupportFlags = IMBitSupportFlags | CV_SUP;
	}

	// Evaluate Data E, BIT 2 - Exhaust Gas Recirculation (EGR) support - must be 1 for at least one ECU for Diesel engines
	if ( (pPid->Data[4] & 0x04) == 0x04 )
	{
		IMBitSupportFlags = IMBitSupportFlags | EGR_SUP;
	}

	// Evaluate Data E, BIT 3 - Variable Valve Timing (VVT) support
//	if ( pPid->Data[4] & 0x08 )
//	{
//		// Variable Valve Timing Monitor is not required to be supported by any vehicle
//	}

	// Evaluate Data E, BIT 4 - Exhaust Gas Sensor (EGS) status
	// if EGS is supported
	if ( (pPid->Data[4] & 0x01) == 0x01 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[4] & 0x10) == 0x00 &&
		     geTestPhase == eTestNoDTC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EGS Monitor must be incomplete (EGS_RDY = 1) after Clear Codes\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 4 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[4] & 0x10) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EGS Monitor must be complete (EGS_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[4] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported EGS Monitor (EGS_SUP = 0) must be complete (EGS_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data E, BIT 5 - Crankcase Ventilation (CV) status
	// if CV is supported
	if ( (pPid->Data[4] & 0x02) == 0x02 )
	{
		// Bit 5 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		if ( (pPid->Data[4] & 0x20) != 0x00 &&
		     geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CV Monitor must be complete (CV_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[4] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported CV Monitor (CV_SUP = 0) must be complete (CV_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data E, BIT 6 - Exhaust Gas Recirculation (EGR) status
	// if EGR supported
	if ( (pPid->Data[4] & 0x04) == 0x04 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[4] & 0x40) == 0x00 &&
		     geTestPhase == eTestNoDTC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EGR Monitor must be incomplete (EGR_RDY = 1) after Clear Codes\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 6 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[4] & 0x40) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  EGR Monitor must be complete (EGR_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[4] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported EGR Monitor (EGR_SUP = 0) must be complete (EGR_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data E, BIT 7 - Variable Valve Timing (VVT) status
	// if VVT supported
	if ( (pPid->Data[4] & 0x08) == 0x08 )
	{
		// Must be incomplete after Clear Codes
		if ( (pPid->Data[4] & 0x80) == 0x00 &&
		     geTestPhase == eTestNoDTC )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  VVT monitor must be incomplete (VVT_RDY = 1) after Clear Codes\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 7 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[4] & 0x80) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  VVT Monitor must be complete (VVT_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[4] & 0x80) == 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported VVT Monitor (VVT_SUP = 0) must be complete (VVT_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}


	// Evaluate Data F, BIT 0 - Direct Ozone Radiator (DOR) support
//	if ( pPid->Data[5] & 0x01 )
//	{
//		// Direct Ozone Radiator Monitor is not required to be supported by any vehcile
//	}

	// Evaluate Data F, BIT 1 - Cold Start Emission Reduction (CSER) support - must be 1 for at least one ECU for all engines
	if ( (pPid->Data[5] & 0x02) == 0x02 )
	{
		IMBitSupportFlags = IMBitSupportFlags | CSER_SUP;
	}

	// Evaluate Data F, BIT 2 - NOx Adsorber Catalyst (NAC) support
	// Must be clear for Gasoline vehicles
	if ( (pPid->Data[5] & 0x04) == 0x04 &&
	     gstUserInput.eFuelType == GASOLINE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NAC Monitor supported (NAC_SUP = 1) (Must not be supported for Gasoline vehicles)\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data F, BIT 3 - Other emission-related strategy or component (OTH) support
//	if ( pPid->Data[5] & 0x08 )
//	{
//		// Other emission-related strategy or component monitor is not required to be supported by any vehicle
//	}

	// Evaluate Data F, BIT 4 - Direct Ozone Radiator (DOR) status
	// if DOR is supprted
	if ( (pPid->Data[5] & 0x01) == 0x01 )
	{
		// Must be clear after Clear Codes
		if ( (pPid->Data[5] & 0x10) == 0x00 &&
		     (geTestPhase == eTestNoDTC && gTestSubsection == 6) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  DOR Monitor must be incomplete (DOR_RDY = 1) after Clear Codes).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 4 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 10.6 and Test 11 where it must be complete (0)./
		else if ( (pPid->Data[5] & 0x10) != 0x00 &&
		          ((geTestPhase == eTestInUseCounters && gTestSubsection == 6) ||
		            geTestPhase == eTestPerformanceCounters) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  DOR Monitor must be complete (DOR_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[5] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported DOR Monitor (DOR_SUP = 0) must be complete (DOR_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data F, BIT 5 - Cold Start Emission Reduction (CSER) status
	// if CSER supported
	if ( (pPid->Data[5] & 0x02) == 0x02 )
	{
		// Must be clear after Clear Codes
		if ( (pPid->Data[5] & 0x20) == 0x00 &&
		     ((geTestPhase == eTestNoDTC         && gTestSubsection == 6) ||
		      (geTestPhase == eTestInUseCounters && gTestSubsection == 6)) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CSER Monitor must be incomplete (CSER_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 5 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[5] & 0x20) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  CSER Monitor must be complete (CSER_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[5] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported CSER Monitor (CSER_SUP = 0) must be complete (CSER_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data F, BIT 6 - NOx Adsorber Catalyst (NAC) status
	// Must be clear for Gasoline vehicles
	if ( (pPid->Data[5] & 0x40) == 0x40 &&
	     gstUserInput.eFuelType == GASOLINE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  NAC Monitor incomplete (NAC_RDY = 1) (must be complete (0) for Gasoline vehicles).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}
	// if NAC supported
	if ( (pPid->Data[5] & 0x04) == 0x04 )
	{
		// Must be clear after Clear Codes
		if ( (pPid->Data[5] & 0x40) == 0x00 &&
		     ((geTestPhase == eTestNoDTC         && gTestSubsection == 6) ||
		      (geTestPhase == eTestInUseCounters && gTestSubsection == 6)) &&
		     gstUserInput.eFuelType == DIESEL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NAC Monitor must be incomplete (NAC_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 6 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[5] & 0x40) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  NAC Monitor must be complete (NAC_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[5] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported NAC Monitor (NAC_SUP = 0) must be complete (NAC_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data F, BIT 7 - Other Emission-Related Strategy/Component monitoring (OTH) status
	// if OTH supported
	if ( (pPid->Data[5] & 0x08) == 0x08 )
	{
		// Must be clear after Clear Codes
		if ( (pPid->Data[5] & 0x80) == 0x00 &&
		     ((geTestPhase == eTestNoDTC         && gTestSubsection == 6) ||
		      (geTestPhase == eTestInUseCounters && gTestSubsection == 6)) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  OTH Monitor must be incomplete (OTH_RDY = 1) after Clear Codes.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		// Bit 7 may be 0 or 1 w/ or wo/ Engine running
		// except in Test 11 where it must be complete (0)./
		else if ( (pPid->Data[5] & 0x80) != 0x00 &&
		          geTestPhase == eTestPerformanceCounters )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  OTH Monitor must be complete (OTH_RDY = 0).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// Unsupported monitor must indicate complete
	else if ( (pPid->Data[5] & 0x80) == 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported OTH Monitor (OTH_SUP = 0) must be complete (OTH_RDY = 0).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	if ( bTestFailed == TRUE )
	{
		return FAIL;
	}
	else
	{
		return PASS;
	}
}


void VerifyPidF502Data ( BYTE EcuIdx, PID *pPid )
{
	bSupportEnded         = FALSE;
	bNoncontiguousSupport = FALSE;

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F502  Misfire Cylinders 1-8 Current Data Support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    MIS%d_CUR_DCY_SUP = %s\n",
		     BitIndex + 1,
		     (pPid->Data[0] >> BitIndex) & 0x01 ? "YES" : "NO" );

		// if the support bit is clear, no later support bits should be set
		if ( ((pPid->Data[0] >> BitIndex) & 0x01) == 0 )
		{
			bSupportEnded = TRUE;
			if ( ((pPid->Data[0] >> BitIndex) & 0xFE) != 0 )
			{
				bNoncontiguousSupport = TRUE;
			}
		}
	}

	if ( (pPid->Data[0] & 0x01) != 0x01 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F502  Cylinder #1 must be supported.\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( bNoncontiguousSupport == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F502  Non-contiguous cylinder support.\n",
		      GetEcuId ( EcuIdx ) );
	}

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		if ( (pPid->Data[0] >> BitIndex) & 0x01 )
		{
			TempData_long = (pPid->Data[(BitIndex*2) + 1] << 8) +
			                 pPid->Data[(BitIndex*2) + 2];
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "                    MIS%d_CUR_DCY  = %d\n",
			      BitIndex + 1,
			      TempData_long );
		}
	}
}


void VerifyPidF503Data ( BYTE EcuIdx, PID *pPid )
{
	bNoncontiguousSupport = FALSE;

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F503  Misfire Cylinders 9-16 Current Data Support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    MIS%d_CUR_DCY_SUP = %s\n",
		     BitIndex + 9,
		     (pPid->Data[0] >> BitIndex) & 0x01 ? "YES" : "NO" );

		// if the support bit is clear, no later support bits should be set
		if ( ((pPid->Data[0] >> BitIndex) & 0x01) == 0 )
		{
			if ( ((pPid->Data[0] >> BitIndex) & 0xFE) != 0 )
			{
				bNoncontiguousSupport = TRUE;
			}
		}
	}

	// if $F502 had any cylinders (1-8) not supported, $F503 shouldn't have any cylinders (9-16) supported
	if ( bSupportEnded == TRUE &&
	     (pPid->Data[0] & 0xFF) != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F503  supports cylinders when $F502 had cylinders it didn't support.\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( bNoncontiguousSupport == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F503  Non-contiguous cylinder support.\n",
		      GetEcuId ( EcuIdx ) );
	}

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		if ( (pPid->Data[0] >> BitIndex) & 0x01 )
		{
			TempData_long = (pPid->Data[(BitIndex*2) + 1] << 8) +
			                 pPid->Data[(BitIndex*2) + 2];
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "                    MIS%d_CUR_DCY  = %d\n",
			      BitIndex + 9,
			      TempData_long );
		}
	}
}


void VerifyPidF504Data ( BYTE EcuIdx, PID *pPid )
{
	bSupportEnded         = FALSE;
	bNoncontiguousSupport = FALSE;

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F504  Misfire Cylinders 1-8 EWMA Data Support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    MIS%d_EWMA_SUP = %s\n",
		     BitIndex+1,
		     (pPid->Data[0] >> BitIndex) & 0x01 ? "YES" : "NO" );

		// if the support bit is clear, no later support bits should be set
		if ( ((pPid->Data[0] >> BitIndex) & 0x01) == 0 )
		{
			bSupportEnded = TRUE;
			if ( ((pPid->Data[0] >> BitIndex) & 0xFE) != 0 )
			{
				bNoncontiguousSupport = TRUE;
			}
		}
	}

	if ( (pPid->Data[0] & 0x01) != 0x01 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F504  Cylinder #1 must be supported.\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( bNoncontiguousSupport == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F504  Non-contiguous cylinder support.\n",
		      GetEcuId ( EcuIdx ) );
	}

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		if ( (pPid->Data[0] >> BitIndex) & 0x01 )
		{
			TempData_long = (pPid->Data[(BitIndex*2) + 1] << 8) +
			                 pPid->Data[(BitIndex*2) + 2];
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "                    MIS%d_EWMA  = %d\n",
			      BitIndex + 1,
			      TempData_long );
		}
	}
}


void VerifyPidF505Data ( BYTE EcuIdx, PID *pPid )
{
	bNoncontiguousSupport = FALSE;

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F505  Misfire Cylinders 9-16 EWMA Data Support = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0] );

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                    MIS%d_EWMA_SUP = %s\n",
		     BitIndex + 9,
		     (pPid->Data[0] >> BitIndex) & 0x01 ? "YES" : "NO" );

		// if the support bit is clear, no later support bits should be set
		if ( ((pPid->Data[0] >> BitIndex) & 0x01) == 0 )
		{
			if ( ((pPid->Data[0] >> BitIndex) & 0xFE) != 0 )
			{
				bNoncontiguousSupport = TRUE;
			}
		}
	}

	// if $F504 had any cylinders (1-8) not supported, $F505 shouldn't have any cylinders (9-16) supported
	if ( bSupportEnded == TRUE &&
	     (pPid->Data[0] & 0xFF) != 0 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F505  supports cylinders when $F504 had cylinders it didn't support.\n",
		      GetEcuId ( EcuIdx ) );
	}

	if ( bNoncontiguousSupport == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  $F505  Non-contiguous cylinder support.\n",
		      GetEcuId ( EcuIdx ) );
	}

	for ( BitIndex = 0;
	      BitIndex < 8;
	      BitIndex++ )
	{
		// if the support bit is set, display and evaluate the corresponding data
		if ( (pPid->Data[0] >> BitIndex) & 0x01 )
		{
			TempData_long = (pPid->Data[(BitIndex*2) + 1] << 8) +
			                 pPid->Data[(BitIndex*2) + 2];
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "                    MIS%d_EWMA  = %d\n",
			      BitIndex + 9,
			      TempData_long );

			if ( bEngineDontCare == FALSE && gbEngineWarm == FALSE &&  // test 5.6 & 5.10 )
			     TempData_long != 0x00 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  $F505  Counts for all supported cylinders must be $00 after clearing DTCs.\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
	}
}




/*******************************************************************************
**
**  Function:  DisplayPid01
**
**  Purpose:   Display bit name and value of PID $F401
**
*******************************************************************************/
void DisplayPid01 ( BYTE EcuIdx,  // index of associated ECU
                    BOOL bCC )            // Called from ClearCodes?
{
	PID  *pPid;

	pPid = (PID *)&gstResponse[EcuIdx].PID;

	if ( !bCC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F401  IM Readiness Data  Byte A = $%02X  B = $%02X  C = $%02X  D = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[0],
		      pPid->Data[1],
		      pPid->Data[2],
		      pPid->Data[3] );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "         %-9s = %-7d    %-9s = %s\n",
		      "DTC_CNT",  (pPid->Data[0] & 0x7F),
		      "MIL",      (pPid->Data[0] & 0x80) ? "ON" : "OFF" );
	}
	else
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $F401  IM Readiness Data (from the last PID $F401 request)  Byte B = $%02X  C = $%02X  D = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      pPid->Data[1],
		      pPid->Data[2],
		      pPid->Data[3] );
	}

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      "MIS_SUP",  (pPid->Data[1] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "MIS_RDY",  (pPid->Data[1] & 0x10) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      "FUEL_SUP", (pPid->Data[1] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "FUEL_RDY", (pPid->Data[1] & 0x20) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      "CCM_SUP",  (pPid->Data[1] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "CCM_RDY",  (pPid->Data[1] & 0x40) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "HCCAT_SUP" : "CAT_SUP",  (pPid->Data[2] & 0x01) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "HCCAT_RDY" : "CAT_RDY",  (pPid->Data[3] & 0x01) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "NCAT_SUP"  : "HCAT_SUP", (pPid->Data[2] & 0x02) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "NCAT_RDY"  : "HCAT_RDY", (pPid->Data[3] & 0x02) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "reserved"  : "EVAP_SUP", (pPid->Data[2] & 0x04) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "reserved"  : "EVAP_RDY", (pPid->Data[3] & 0x04) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "BP_SUP"    : "AIR_SUP",  (pPid->Data[2] & 0x08) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "BP_RDY"    : "AIR_RDY",  (pPid->Data[3] & 0x08) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "reserved"  : "GPF_SUP",  (pPid->Data[2] & 0x10) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "reserved"  : "GPF_RDY",  (pPid->Data[3] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "EGS_SUP"   : "O2S_SUP",  (pPid->Data[2] & 0x20) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "EGS_RDY"   : "O2S_RDY",  (pPid->Data[3] & 0x20) ? "1 (NO)" : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "         %-9s = %-7s    %-9s = %s\n",
	      gstUserInput.eFuelType == DIESEL ? "PM_SUP"    : "HTR_SUP",  (pPid->Data[2] & 0x40) ? "1 (YES)" : "0 (NO)",
	      gstUserInput.eFuelType == DIESEL ? "PM_RDY"    : "HTR_RDY",  (pPid->Data[3] & 0x40) ? "1 (NO)" : "0 (YES)" );

	if ( !bCC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "         %-9s = %-7s    %-9s = %s\n",
		      "EGR_SUP",  (pPid->Data[2] & 0x80) ? "1 (YES)" : "0 (NO)",
		      "EGR_RDY",  (pPid->Data[3] & 0x80) ? "1 (NO)" : "0 (YES)" );
	}
}




/*******************************************************************************
**
**  Function:  DisplayPIDF501
**
**  Purpose:
**
*******************************************************************************/
void DisplayPIDF501 ( BYTE EcuIdx )
{
	PID  *pPid;          // pointer to PID Data


	pPid = &gstResponse[EcuIdx].PIDF501;

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $F501  Byte A = $%02X  B = $%02X  C = $%02X  D = $%02X  E = $%02X  F = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0],
	      pPid->Data[1],
	      pPid->Data[2],
	      pPid->Data[3],
	      pPid->Data[4],
	      pPid->Data[5] );

	// $F501 Byte A (0) decode
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7d    %-10s = %s\n",
	      "DTC_CNT",  (pPid->Data[0] & 0x7F),
	      "MIL",      (pPid->Data[0] & 0x80) ? "ON" : "OFF" );

	// $F501 Byte B (1) decode
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "MIS_SUP",  (pPid->Data[1] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "MIS_RDY",  (pPid->Data[1] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "FUEL_SUP", (pPid->Data[1] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "FUEL_RDY", (pPid->Data[1] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "CCM_SUP",  (pPid->Data[1] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "CCM_RDY",  (pPid->Data[1] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "COOL_SUP", (pPid->Data[1] & 0x08) ? "1 (YES)" : "0 (NO)",
	      "COOL_RDY", (pPid->Data[1] & 0x80) ? "1 (NO)"  : "0 (YES)" );

	// $F501 Byte C (2) decode
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "CAT_SUP",   (pPid->Data[2] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "CAT_RDY",   (pPid->Data[2] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "HCCAT_SUP", (pPid->Data[2] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "HCCAT_RDY", (pPid->Data[2] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "HCAT_SUP",  (pPid->Data[2] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "HCAT_RDY",  (pPid->Data[2] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "NCAT_SUP",  (pPid->Data[2] & 0x08) ? "1 (YES)" : "0 (NO)",
	      "NCAT_RDY",  (pPid->Data[2] & 0x80) ? "1 (NO)"  : "0 (YES)" );

	// $F501 Byte D (3) decode
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "EVAP_SUP",  (pPid->Data[3] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "EVAP_RDY",  (pPid->Data[3] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "AIR_SUP",   (pPid->Data[3] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "AIR_RDY",   (pPid->Data[3] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "BP_SUP",    (pPid->Data[3] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "BP_RDY",    (pPid->Data[3] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "PF_SUP",    (pPid->Data[3] & 0x08) ? "1 (YES)" : "0 (NO)",
	      "PF_RDY",    (pPid->Data[3] & 0x80) ? "1 (NO)"  : "0 (YES)" );

	// $F501 Byte E (4) decode
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "EGS_SUP",   (pPid->Data[4] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "EGS_RDY",   (pPid->Data[4] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "CV_SUP",    (pPid->Data[4] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "CV_RDY",    (pPid->Data[4] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "EGR_SUP",   (pPid->Data[4] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "EGR_RDY",   (pPid->Data[4] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "VVT_SUP",   (pPid->Data[4] & 0x08) ? "1 (YES)" : "0 (NO)",
	      "VVT_RDY",   (pPid->Data[4] & 0x80) ? "1 (NO)"  : "0 (YES)" );

	// $F501 Byte F (5) decode
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "DOR_SUP",   (pPid->Data[5] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "DOR_RDY",   (pPid->Data[5] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "CSER_SUP",  (pPid->Data[5] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "CSER_RDY",  (pPid->Data[5] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "NAC_SUP",   (pPid->Data[5] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "NAC_RDY",   (pPid->Data[5] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                    %-9s = %-7s    %-10s = %s\n",
	      "OTH_SUP",   (pPid->Data[5] & 0x08) ? "1 (YES)" : "0 (NO)",
	      "OTH_RDY",   (pPid->Data[5] & 0x80) ? "1 (NO)"  : "0 (YES)" );
}




/*******************************************************************************
**
**  Function:  VerifyIM_Ready
**
**  Purpose:   Request PID $F501 and check IM Ready
**
*******************************************************************************/
STATUS VerifyIM_Ready ( void )
{
	REQ_MSG        stReqMsg;
	PID           *pPid;
	BYTE           EcuIdx;

	unsigned short PIDDataCnt = 0;

	BOOL           bTestFailed = FALSE;


	if ( IsIDSupported ( ALLECUS, PF5REQUEST, 0xF501 ) == FALSE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "PID $F501 not supported\n" );
		bTestFailed = TRUE;
	}


	stReqMsg.SID      = 0x22;
	stReqMsg.NumIds   = 1;
	stReqMsg.u.DID[0] = 0xF501;
	if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "PID $F501 request\n" );
		bTestFailed = TRUE;
	}
	else
	{
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( gstResponse[EcuIdx].PIDSize != 0 )
			{
				PIDDataCnt++;
		
				SavePIDF501Data ( EcuIdx, TRUE );
				pPid = (PID *)&gstResponse[EcuIdx].PID[0];

				IMBitSupportFlags = 0;
				// Verify that all PID data is valid
				if ( VerifyPidF501Data ( EcuIdx, pPid ) != PASS )
				{
					bTestFailed = TRUE;
				}
			}
		}

		if ( PIDDataCnt == 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "No PID $F501 data\n" );
			bTestFailed = TRUE;
		}
	}


	// if this is test 11.3, check for appropriate value of PID $F431 and $F44E
	if ( geTestPhase == eTestPerformanceCounters && gTestSubsection == 3 )
	{
		// If PID $F431 is supported, request it
		if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF431 ) == TRUE )
		{
			stReqMsg.SID      = 0x22;
			stReqMsg.NumIds   = 1;
			stReqMsg.u.DID[0] = 0xF431;
			if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "PID $F431 request\n" );
				bTestFailed = TRUE;
			}
			else
			{
				// Check the data to see if it is valid
				for ( EcuIdx = 0;
				      EcuIdx < gNumOfECUs;
				      EcuIdx++ )
				{
					if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF431 ) == TRUE )
					{
						pPid = (PID *)&gstResponse[EcuIdx].PID[0];
						TempData_long = ((pPid->Data[0] << 8) +
						                  pPid->Data[1]);
						if ( gstResponse[EcuIdx].PIDSize != 0 )
						{
							if ( TempData_long == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $F431 is 0\n",
								      GetEcuId ( EcuIdx ) );
								bTestFailed = TRUE;
							}
						}
						else
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $F431 size is 0\n",
							      GetEcuId ( EcuIdx ) );
							bTestFailed = TRUE;
						}
					}
				}
			}
		}

		// If PID $4E is supported, request it
		if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF44E ) == TRUE )
		{
			stReqMsg.SID      = 0x22;
			stReqMsg.NumIds   = 1;
			stReqMsg.u.DID[0] = 0xF44E;
			if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "PID $F44E request\n" );
				bTestFailed = TRUE;
			}
			else
			{
				// Check the data to see if it is valid
				for ( EcuIdx = 0;
				      EcuIdx < gNumOfECUs;
				      EcuIdx++ )
				{
					if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF44E ) == TRUE )
					{
						pPid = (PID *)&gstResponse[EcuIdx].PID[0];
						TempData_long = ((pPid->Data[0] << 8) +
						                  pPid->Data[1]);
						if ( gstResponse[EcuIdx].PIDSize != 0 )
						{
							if ( TempData_long == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $F44E is 0\n",
								      GetEcuId ( EcuIdx ) );
								bTestFailed = TRUE;
							}
						}
						else
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $F44E size is 0\n",
							      GetEcuId ( EcuIdx ) );
							bTestFailed = TRUE;
						}
					}
				}
			}
		}
	}

	if (bTestFailed == TRUE)
	{
		return FAIL;
	}
	else
	{
		return PASS;
	}
}




/*******************************************************************************
**
**  Function:  VerifyDSCC
**
**  Purpose:   Request PID $F431 (or $F44E) and check Distance (or Engine Runtime)
**             Since Code Clear
**
*******************************************************************************/
STATUS VerifyDSCC ( void )
{
	REQ_MSG        stReqMsg;
	BYTE           EcuIdx;

	WORD           Pid;
	WORD           PIDData;

	BOOL           bTestFailed = FALSE;


	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF431 ) == TRUE )
	{
		Pid = 0xF431;
	}
	else if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF44E ) == TRUE )
	{
		Pid = 0xF44E;
	}
	else
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "PID $F431 and $F44E not supported\n" );
		bTestFailed = TRUE;
	}

	if ( bTestFailed == FALSE )
	{
		stReqMsg.SID      = 0x22;
		stReqMsg.NumIds   = 1;
		stReqMsg.u.DID[0] = Pid;
		if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $%04X request\n",
			      Pid );
			bTestFailed = TRUE;
		}
		else
		{
			for ( EcuIdx = 0;
			      EcuIdx < gNumOfECUs;
			      EcuIdx++ )
			{
				if ( gstResponse[EcuIdx].PIDSize != 0 )
				{
					PIDData = (gstResponse[EcuIdx].PID[0]<< 8) +
					           gstResponse[EcuIdx].PID[1];

					// Verify that PID data is greater than zero
					if ( PIDData <= 0 )
					{
						bTestFailed = TRUE;
					}
				}
			}
		}
	}

	if (bTestFailed == TRUE)
	{
		return FAIL;
	}
	else
	{
		return PASS;
	}
}




/*******************************************************************************
**
**  Function:  DetermineVariablePIDSize
**
**  Purpose:   Determine number of data bytes in PIDs $06 - $09, $55 - $58
**
******************************************************************************/
STATUS DetermineVariablePIDSize ( void )
{
	REQ_MSG       stReqMsg;
	PID          *pPid;
	BYTE          EcuIdx;

	BYTE          PidArray[MAX_ECUS];
	unsigned long EcuIdIdx[MAX_ECUS];

	BYTE          NumResp;


	// only need to check once
	if ( gVariablePIDSize != 0 )
	{
		return PASS;
	}

	// -1 ==> cannot determine the PID size
	gVariablePIDSize = -1;

	// only check if needed
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF406 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF407 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF408 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF409 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF455 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF456 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF457 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF458 ) == FALSE )
	{
		return PASS;
	}

	// cannot support both PID $13 and $1D
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF413 ) == TRUE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0xF41D ) == TRUE )
	{
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF413 ) == TRUE )
			{
				Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  Supports PID $F413\n",
				      GetEcuId ( EcuIdx ));
			}

			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF41D ) == TRUE )
			{
				Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  Supports PID $F41D\n",
				      GetEcuId ( EcuIdx ));
			}
		}
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Both PID $F413 and $F41D are supported\n" );
		return FAIL;
	}

	// check PID $13 first
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF413 ) == TRUE )
	{
		stReqMsg.SID      = 0x22;
		stReqMsg.NumIds   = 1;
		stReqMsg.u.DID[0] = 0xF413;
		if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $F413 request\n" );
			return FAIL;
		}

		NumResp = 0;
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF413 ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PIDSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].PID);
					if ( pPid->PIDLSB == 0x13 )
					{
						Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  PID $F413  O2SLOC = $%02X\n",
						      GetEcuId ( EcuIdx ),
						      pPid->Data[0] );
						EcuIdIdx[NumResp] = EcuIdx;
						PidArray[NumResp++] = pPid->Data[0];
					}
				}
			}
		}

		if ( NumResp == 0 || NumResp > 2 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $F413 supported by %d ECUs (1 to 2 expected)\n",
			      NumResp);
			return FAIL;
		}

		gVariablePIDSize = 1;
		return PASS;
	}

	// check PID $1D second
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF41D ) == TRUE )
	{
		stReqMsg.SID      = 0x22;
		stReqMsg.NumIds   = 1;
		stReqMsg.u.DID[0] = 0xF41D;
		if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $F41D request\n" );
			return FAIL;
		}

		NumResp = 0;
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF41D ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PIDSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].PID);
					if ( pPid->PIDLSB == 0x1D )
					{
						EcuIdIdx[NumResp] = EcuIdx;
						PidArray[NumResp++] = pPid->Data[0];
					}
				}
			}
		}

		if ( NumResp == 1 )
		{
			gVariablePIDSize = (PidArray[0] == 0xFF) ? 2 : 1;
			return PASS;
		}

		else if ( NumResp == 2 )
		{
			if ( (PidArray[0] | PidArray[1]) != 0xFF)
			{
				gVariablePIDSize = 1;
				return PASS;
			}

			if ( (PidArray[0] == 0xF0 && PidArray[1] == 0x0F) ||
			     (PidArray[0] == 0x0F && PidArray[1] == 0xF0) )
			{
				gVariablePIDSize = 2;
				return PASS;
			}

			if ( (PidArray[0] == 0xCC && PidArray[1] == 0x33) ||
			     (PidArray[0] == 0x33 && PidArray[1] == 0xCC) )
			{
				gVariablePIDSize = 2;
				return PASS;
			}

			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Unable to determine number of data bytes in PIDs $F406 - $F409\n" );
			return FAIL;
		}

		// NumResp == 0 or NumResp > 2
		else
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      " PID $F41D supported by %d ECUs ( 1 to 2 expected)\n",
			      NumResp);
			return FAIL;
		}
	}

	Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "Neither PID $F413 nor $F41D are supported\n" );
	return FAIL;
}


/*******************************************************************************
**
**  Function:  GetPid4FArray
**
**  Purpose:   Copy PID $4F values into an array.
**
*******************************************************************************/
STATUS GetPid4FArray ( void )
{
	REQ_MSG  stReqMsg;
	PID     *pPid;
	BYTE     EcuIdx;


	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUs;
	      EcuIdx++ )
	{
		Pid4F[EcuIdx][0] = 0x00;
		Pid4F[EcuIdx][1] = 0x00;
		Pid4F[EcuIdx][2] = 0x00;
		Pid4F[EcuIdx][3] = 0x00;
	}

	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF44F ) == TRUE )
	{
		stReqMsg.SID      = 0x22;
		stReqMsg.NumIds   = 1;
		stReqMsg.u.DID[0] = 0xF44F;

		if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $F44F request\n" );
			return FAIL;
		}

		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF44F ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PIDSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].PID);
					if ( pPid->PIDLSB == 0x4F )
					{
						Pid4F[EcuIdx][0] = pPid->Data[0];
						Pid4F[EcuIdx][1] = pPid->Data[1];
						Pid4F[EcuIdx][2] = pPid->Data[2];
						Pid4F[EcuIdx][3] = pPid->Data[3];
					}
				}
			}
		}
	}
	return PASS;
}


/*******************************************************************************
**
**  Function:  GetPid50Array
**
**  Purpose:   Copy PID $50 values into an array.
**
*******************************************************************************/
STATUS GetPid50Array ( void )
{
	REQ_MSG  stReqMsg;
	PID     *pPid;
	BYTE     EcuIdx;


	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0xF450 ) == TRUE )
	{
		stReqMsg.SID      = 0x22;
		stReqMsg.NumIds   = 1;
		stReqMsg.u.DID[0] = 0xF450;

		if ( RequestSID ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "PID $F450 request\n" );
			return FAIL;
		}

		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0xF450 ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PIDSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].PID);
					if ( pPid->PIDLSB == 0x50 )
					{
						Pid50[EcuIdx][0] = pPid->Data[0];
						Pid50[EcuIdx][1] = pPid->Data[1];
						Pid50[EcuIdx][2] = pPid->Data[2];
						Pid50[EcuIdx][3] = pPid->Data[3];
					}
				}
			}
		}
	}
	return PASS;
}


/*******************************************************************************
**
**  Function:  GetHoursMinsSecs
**
**  Purpose:   Convert the time (in seconds) into hours, minutes and seconds .
**
*******************************************************************************/
void GetHoursMinsSecs ( unsigned long time,
                        unsigned long *pHours,
                        unsigned long *pMins,
                        unsigned long *pSecs )
{
	*pHours = time/3600;

	*pMins = (time - (*pHours * 3600)) / 60;

	*pSecs = time - (*pHours * 3600) - (*pMins * 60);
}
