NOTE "CREATOR" "Designer Version: 8.2.0.17";
NOTE "CAPTURE" "8.2.0.17";
NOTE "DEVICE" "AFS600";
NOTE "PACKAGE" "AFS600-fg256";
NOTE "DATE" "2008/01/23";
NOTE "STAPL_VERSION" "JESD71";
NOTE "IDCODE" "033261cf";
NOTE "DESIGN" "NVM_TOP";
NOTE "CHECKSUM" "0000";
NOTE "SECURITY" "Disable";
NOTE "ALG_VERSION" "17";
NOTE "MAP_VERSION" "1";
NOTE "TOOL_VERSION" "1";
NOTE "MAX_FREQ" "10000000";
NOTE "SILSIG" "00000000";
NOTE "TRACKING_SAR" "72850";
NOTE "SPEED_GRAD" "-2";
NOTE "TEMP_GRAD" "COM";
NOTE "PRG_BSR_SET_IO" "Z";

ACTION DETECT_CALIB =
       NR_INITIALIZE, 
       DO_DETECT_CALIB;
       
ACTION POPULATE_CALIB = 
       NW_INITIALIZE,
       DO_POPULATE_CALIB;



DATA CONSTBLOCK;
    INTEGER IEEE1532=0;
    INTEGER STAPL=1;
    INTEGER DIRECTC=2;
    INTEGER PDB=3;
    INTEGER SVF=4;
    INTEGER FP=0;
    INTEGER FPLITE=1;
    INTEGER FP3=2;
    INTEGER SCULPTW=3;
    INTEGER BPW=4;
    INTEGER DIRECTCP=5;
    INTEGER STP=6;
    INTEGER FP33=0;
    INTEGER FP34=1;
    INTEGER FP40=2;
    INTEGER FP41=3;
    INTEGER FP42=4;
    INTEGER FP50=5;
    INTEGER FP51=6;
    INTEGER FP60=7;
    INTEGER FP61=8;
    INTEGER FP62=9;
    INTEGER UNKNOWN=127;
    INTEGER UNSPECIFIED=0;
    INTEGER QN132=1;
    INTEGER VQ100=2;
    INTEGER TQ144=3;
    INTEGER PQ208=4;
    INTEGER FG144=5;
    INTEGER FG256=6;
    INTEGER FG484=7;
    INTEGER FG676=8;
    INTEGER FG896=9;
    INTEGER QN108=10;
    INTEGER QN180=11;
    INTEGER TQ100=12;
    INTEGER CQ208=13;
    INTEGER FG1152=14;
    INTEGER BG456=15;
    INTEGER UNDEFINED=63;
    INTEGER GRADE_UNSPEC=0;
    INTEGER GRADE_1=1;
    INTEGER GRADE_2=2;
    INTEGER GRADE_3=3;
    INTEGER GRADE_F=4;
    INTEGER GRADE_STD=5;
    INTEGER GRADE_4=6;
    INTEGER GRADE_UNDEF=7;
ENDDATA;

DATA PARAMETERS;
    INTEGER FREQ =4;
ENDDATA;

DATA GV;
    INTEGER ULOPT1_BITLOCATION =23;
    INTEGER ULOPT0_BITLOCATION =22;
    INTEGER ULUWE_BITLOCATION =21;
    INTEGER ULARE_BITLOCATION =20;
    INTEGER ULUPC_BITLOCATION =19;
    INTEGER ULUFE_BITLOCATION =18;
    INTEGER ULUFP_BITLOCATION =17;
    INTEGER ULUFJ_BITLOCATION =16;
    INTEGER ULFLR_BITLOCATION =15;
    INTEGER ULULR_BITLOCATION =14;
    INTEGER ULAWE_BITLOCATION =13;
    INTEGER ULARD_BITLOCATION =12;
    INTEGER ULNR0_BITLOCATION =0;
    INTEGER ULNW0_BITLOCATION =1;
    INTEGER ULNC0_BITLOCATION =2;
    INTEGER ULNR1_BITLOCATION =3;
    INTEGER ULNW1_BITLOCATION =4;
    INTEGER ULNC1_BITLOCATION =5;
    INTEGER ULNR2_BITLOCATION =6;
    INTEGER ULNW2_BITLOCATION =7;
    INTEGER ULNC2_BITLOCATION =8;
    INTEGER ULNR3_BITLOCATION =9;
    INTEGER ULNW3_BITLOCATION =10;
    INTEGER ULNC3_BITLOCATION =11;
    BOOLEAN BUFF128[128];
    BOOLEAN BUFF32[32];
    INTEGER I;
    INTEGER J;
    INTEGER TEMP;
    INTEGER SDNUMBER;
    INTEGER ROWNUMBER;
    INTEGER DATAINDEX =0;
    INTEGER FROMROWNUMBER =1;
    INTEGER AESBLOCK;
    BOOLEAN ID[32];
    BOOLEAN PASS = 1;
    BOOLEAN FADDR[3];
    INTEGER STATUS =0;
    BOOLEAN SILSIG[32] = $00000000;
    BOOLEAN ISC_CONFIG_RESULT[18];
    BOOLEAN VERIFYEOL[2];
    BOOLEAN COMBERASESELECT[23];
    BOOLEAN SECKEY_OK = 1;
    BOOLEAN SECREG[56];
    BOOLEAN ULUWE = 0;
    BOOLEAN ULARE = 0;
    BOOLEAN ULUPC = 0;
    BOOLEAN ULUFE = 0;
    BOOLEAN ULUFP = 0;
    BOOLEAN ULUFJ = 0;
    BOOLEAN ULFLR = 0;
    BOOLEAN ULULR = 0;
    BOOLEAN ULAWE = 0;
    BOOLEAN ULARD = 0;
    BOOLEAN ULOPT[2];
    BOOLEAN ULNR0 = 0;
    BOOLEAN ULNW0 = 0;
    BOOLEAN ULNC0 = 0;
    BOOLEAN ULNR1 = 0;
    BOOLEAN ULNW1 = 0;
    BOOLEAN ULNC1 = 0;
    BOOLEAN ULNR2 = 0;
    BOOLEAN ULNW2 = 0;
    BOOLEAN ULNC2 = 0;
    BOOLEAN ULNR3 = 0;
    BOOLEAN ULNW3 = 0;
    BOOLEAN ULNC3 = 0;
    BOOLEAN SUROWCHECKSUM[16];
    INTEGER SUROWCYCLECOUNT =0;
    INTEGER ACT_UROW_CYCLE_COUNT =0;
    BOOLEAN ACT_UROW_DESIGN_NAME[70] = $010204e5ad9fa57c85;
    BOOLEAN SUROWDESIGNNAME[70];
    BOOLEAN SUROWPROGMETHOD[3];
    BOOLEAN ACT_UROW_ALGO_VERSION[7] = $11;
    BOOLEAN SUROWALGOVERSION[7];
    BOOLEAN SUROW_PKG_TYPE[6];
    BOOLEAN ACT_UROW_SW_VERSION[7];
    BOOLEAN SUROW_SW_VERSION[7];
    INTEGER PLAYERVERSIONVARIABLE =0;
    INTEGER SCULPTORMAJORBASE =4;
    INTEGER SCULPTORMINORBASE =50;
    INTEGER PLAYER_VERSION_VARIABLE =0;
    INTEGER SCULPTOR_MAJOR_BASE =4;
    INTEGER SCULPTOR_MINOR_BASE =50;
    BOOLEAN ACT_UROW_PROGRAM_SW[4] = $f;
    BOOLEAN SUROWPROGRAMSW[4];
    BOOLEAN SUROW_SPEED_GRADE[3];
    BOOLEAN SUROW_SRAM_DISTURB[1];
    BOOLEAN ISERASEONLY = 0;
    BOOLEAN ISRESTOREDESIGN = 0;
    BOOLEAN FLAGDISPLAYCYC = 0;
    BOOLEAN BSRPATTERN[1056] = $924924924924924924924924924924924924924924924924
        924924924924924924924924924924924924924924924924924924924924924924924924
        924924924924924924924924924924924924924924924924924924924924924924924924
        924924924924924924924927ffffffffffe4924924924924924924924924924924924924
        ;
    BOOLEAN SAMPLEMASK[1056] = $000000000000000000000000000000000000000000000000
        000000000000000000000000000000000000000000000000000000000000000000000000
        000000000000000000000000000000000000000000000000000000000000000000000000
        000000000000000000000000000000000000000000000000000000000000000000000000
        ;
    BOOLEAN ARRAYRONLY = 1;
    BOOLEAN CHKARRAY = 0;
    BOOLEAN FROMRONLY = 1;
    BOOLEAN CHKFROM = 1;
    BOOLEAN CHKNVM = 1;
    BOOLEAN CHKSEC = 1;
    BOOLEAN PERMLOCK = 0;
    BOOLEAN NVM0RONLY = 1;
    INTEGER HEX[16] = 70,69,68,67,66,65,57,56,55,54,53,52,51,50,49,48;
    INTEGER NVMPOLL =0;
    INTEGER NUMBEROFFROMROWS =8;
    BOOLEAN INITIALIZE_DATA[5] = $00;
    INTEGER SDTILE;
    INTEGER NUMBEROFSDTILES =6;
    INTEGER NUMBEROFMAPROWS =3444;
    INTEGER IDREV;
    INTEGER IDFAB;
    INTEGER BM7DEVICE =0;
    INTEGER BM1DEVICE =0;
    BOOLEAN IDCODEVALUE[32] = $033261cf;
    BOOLEAN IDMASK[32] = $0fffffff;
    INTEGER SECKEYCHK =0;
    INTEGER DESIGNPKGTYPE =6;
    BOOLEAN ACT_UROW_PROG_METHOD[3] = $1;
    INTEGER LABEL_SEPARATOR =0;
ENDDATA;

DATA ECCCHECK;
    INTEGER SYNDROMETABLE[256] = -1,97,98,-1,99,-1,-1,100,101,-1,-1,31,-1,102,30
        ,-1,103,-1,-1,29,-1,28,27,-1,-1,26,25,-1,24,-1,-1,104,105,-1,-1,7,-1,6,5
        ,-1,
    -1,4,3,-1,2,-1,-1,106,-1,0,107,-1,1,-1,-1,108,109,-1,-1,110,-1,111,112,-1,86
        ,-1,-1,87,-1,88,89,-1,-1,90,47,-1,91,-1,-1,46,
    -1,92,45,-1,44,-1,-1,43,42,-1,-1,41,-1,40,93,-1,-1,64,55,-1,54,-1,-1,53,52,-1
        ,-1,51,-1,50,65,-1,48,-1,-1,66,-1,49,67,-1,
    -1,68,69,-1,70,-1,-1,-1,71,-1,-1,72,-1,73,74,-1,-1,75,63,-1,76,-1,-1,62,-1,77
        ,61,-1,60,-1,-1,59,58,-1,-1,57,-1,56,78,-1,
    -1,79,39,-1,38,-1,-1,37,36,-1,-1,35,-1,34,80,-1,32,-1,-1,81,-1,33,82,-1,-1,83
        ,84,-1,85,-1,-1,-1,-1,113,114,-1,115,-1,-1,116,
    117,-1,-1,15,-1,118,14,-1,119,-1,-1,13,-1,12,11,-1,-1,10,9,-1,8,-1,-1,-1,94,-1
        ,-1,23,-1,22,21,-1,-1,20,19,-1,18,-1,-1,-1,
    -1,16,95,-1,17,-1,-1,-1,96,-1,-1,-1,-1,-1,-1,-99;
    BOOLEAN ECCSTR0[120] = $ad2aadea7554eab4d1b4d14b2e4b2e;
    BOOLEAN ECCSTR1[120] = $eaa2eb5d68bad11557155715571557;
    BOOLEAN ECCSTR2[120] = $a66aa7d4daa9b5a699a699a699a699;
    BOOLEAN ECCSTR3[120] = $9e1a9ed3c6a78d38e338e338e338e3;
    BOOLEAN ECCSTR4[120] = $7e067e4fc19f83c0fcc0fcc0fcc0fc;
    BOOLEAN ECCSTR5[120] = $fe01fe3fc07f80ff00ff00ff00ff00;
    BOOLEAN ECCSTR6[120] = $01fffe003fff80ff0000ffff0000ff;
    BOOLEAN ECCSTR7[120] = $01fffe3fc0007f00ffff00ff0000ff;
    BOOLEAN TEMPECCSTR[120];
    BOOLEAN TEMPECC[8];
    BOOLEAN TEMPPARITY;
    BOOLEAN TEMPDATA[120];
    INTEGER ISMARTERASE;
    INTEGER ISEITERATION =10;
ENDDATA;

DATA BITSTREAM;
    BOOLEAN UROW[128];
    BOOLEAN UROW_MASK[128] = $fffffffffffffffffffffffffe01ffc0;
    INTEGER CHECKSUM =0;
ENDDATA;

DATA SECURITY;
    BOOLEAN ULOCK[24] = $008000;
ENDDATA;

DATA NVM_V;
    BOOLEAN NVMADDRESS[35];
    BOOLEAN PROTECTION[5];
    INTEGER PARSIZE =0;
    INTEGER PAR =0;
    INTEGER PAGEADDRESS =0;
    INTEGER OFFSET =0;
    INTEGER NVMDATAINDEX =0;
    INTEGER NVMPROTINDEX =0;
    INTEGER NVMWORDS =0;
    INTEGER NVMWORDCOUNT =0;
    INTEGER NUMOFPART_0 =1;
    BOOLEAN NVMPARSIZE_0[32] = $000001a0;
    INTEGER NVMDATASTREAMSIZE_0 =13312;
    BOOLEAN NVMADDR_0[22] = $083200;
    BOOLEAN NVMDATA_0[13312] = @0Q000O8X000v@300mUs100i2L00W1k30000W0WGo8W000J42
        C00m4A0800O2X0500C1X0600C150700C1X0800C1X0900C1A0K00O242i00m484W10W9G1G3
        00JWG0700c0X0F00C1Ae081Y00O242810m4e0O20W9G80500J0X0L00C1K0O10m4G8m500J0
        X0O00C1K0a10m4G8W600J0X0R00C1K0m10m4G8G700J0X0U00C1KGgbW8A1vH22V4aq88MHG
        6YW031f32Y244bX83ZGg5YmA4fK4obG47X87YGo3Y0749D4oMG4fW8B1Xq38Y0n9y3dOFS2y
        m9g3dGESYtm9O3d8DS2piP0O5;
    BOOLEAN NVMPROTECT_0[3] = $2;
    'BOOLEAN NVMPROTECT_0[3] = $0;
ENDDATA;

DATA CALIB;
    INTEGER CRC1 =0;
    INTEGER CRC2 =0;
    INTEGER CRC3 =0;
    INTEGER CRC4 =0;
    INTEGER NVM0_INDEX =0;
    INTEGER TAG_CRC_INDEX =0;
    INTEGER DATASET1_INDEX =0;
    INTEGER DATASET2_INDEX =0;
    INTEGER DATASET3_INDEX =0;
    INTEGER DATASET4_INDEX =0;
    BOOLEAN TAG_CRC[160];
    BOOLEAN DATASET1[6400];
    BOOLEAN DATASET2[320];
    BOOLEAN DATASET3[1600];
    BOOLEAN DATASET4[4480];
    BOOLEAN IS_CALIBRATED =0;
ENDDATA;


PROCEDURE DO_EXIT USES GV;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $81;
    WAIT IDLE, 20 USEC;
    IF ( ! (STATUS!=0) ) THEN GOTO Label_0;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $07;
    WAIT IDLE, 1 CYCLES;
    Label_0:
    WAIT 200 USEC;
    STATE RESET ;
    EXIT STATUS;
ENDPROC;

PROCEDURE DO_READ_SECURITY USES GV;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $a4;
    WAIT IDLE, 3 CYCLES;
    DRSCAN 56, $00000000000000, CAPTURE SECREG[];
    ULNR0 = SECREG[ULNR0_BITLOCATION];
    ULNW0 = SECREG[ULNW0_BITLOCATION];
    ULNC0 = SECREG[ULNC0_BITLOCATION];
    ULNR1 = SECREG[ULNR1_BITLOCATION];
    ULNW1 = SECREG[ULNW1_BITLOCATION];
    ULNC1 = SECREG[ULNC1_BITLOCATION];
    ULNR2 = SECREG[ULNR2_BITLOCATION];
    ULNW2 = SECREG[ULNW2_BITLOCATION];
    ULNC2 = SECREG[ULNC2_BITLOCATION];
    ULNR3 = SECREG[ULNR3_BITLOCATION];
    ULNW3 = SECREG[ULNW3_BITLOCATION];
    ULNC3 = SECREG[ULNC3_BITLOCATION];
    ULUWE = SECREG[ULUWE_BITLOCATION];
    ULARE = SECREG[ULARE_BITLOCATION];
    ULUPC = SECREG[ULUPC_BITLOCATION];
    ULUFE = SECREG[ULUFE_BITLOCATION];
    ULUFP = SECREG[ULUFP_BITLOCATION];
    ULUFJ = SECREG[ULUFJ_BITLOCATION];
    ULFLR = SECREG[ULFLR_BITLOCATION];
    ULULR = SECREG[ULULR_BITLOCATION];
    ULAWE = SECREG[ULAWE_BITLOCATION];
    ULARD = SECREG[ULARD_BITLOCATION];
    ULOPT[1] = SECREG[ULOPT1_BITLOCATION];
    ULOPT[0] = SECREG[ULOPT0_BITLOCATION];
ENDPROC;

PROCEDURE DO_OUTPUT_SECURITY USES GV;
    PRINT "Security Settings :";
    IF ( ! (ULUFP==1) ) THEN GOTO Label_1;
    PRINT "FlashROM Write/Erase protected by pass key.";
    Label_1:
    IF ( ! (ULUFJ==1) ) THEN GOTO Label_2;
    PRINT "FlashROM Read protected by pass key.";
    Label_2:
    IF ( ! (ULAWE==1) ) THEN GOTO Label_3;
    PRINT "Array Write/Erase protected by pass key.";
    Label_3:
    IF ( ! (ULARD==1) ) THEN GOTO Label_4;
    PRINT "Array Verify protected by pass key.";
    Label_4:
    IF ( ! (ULNW0==1) ) THEN GOTO Label_5;
    PRINT "NVM block 0 Write protected by pass key.";
    Label_5:
    IF ( ! (ULNR0==1) ) THEN GOTO Label_6;
    PRINT "NVM block 0 Read protected by pass key.";
    Label_6:
    IF ( ! (ULNW1==1) ) THEN GOTO Label_7;
    PRINT "NVM block 1 Write protected by pass key.";
    Label_7:
    IF ( ! (ULNR1==1) ) THEN GOTO Label_8;
    PRINT "NVM block 1 Read protected by pass key.";
    Label_8:
    IF ( ! (ULUFE==1) ) THEN GOTO Label_9;
    PRINT "Encrypted FlashROM Programming Enabled.";
    Label_9:
    IF ( ! (ULARE==1) ) THEN GOTO Label_10;
    PRINT "Encrypted FPGA Array Programming Enabled.";
    Label_10:
    IF ( ! (ULNC0==1) ) THEN GOTO Label_11;
    PRINT "Encrypted NVM block 0 Programming Enabled.";
    Label_11:
    IF ( ! (ULNC1==1) ) THEN GOTO Label_12;
    PRINT "Encrypted NVM block 1 Programming Enabled.";
    Label_12:
    PRINT "=========================================";
ENDPROC;

PROCEDURE DO_QUERY_SECURITY USES DO_READ_SECURITY,DO_OUTPUT_SECURITY;
    CALL DO_READ_SECURITY;
    CALL DO_OUTPUT_SECURITY;
ENDPROC;

PROCEDURE READ_UROW USES BITSTREAM,GV;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $c0;
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $a8;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 264 USEC;
    DRSCAN 128, $00000000000000000000000000000000, CAPTURE UROW[];
    SUROWALGOVERSION[6..0] = $00;
    IF ( ! ( (UROW[5]==0)&&(UROW[0]==1)) ) THEN GOTO Label_13;
    SUROWALGOVERSION[5..4] = UROW[24..23];
    Label_13:
    IF ( ! ( (UROW[5]==1)&&(UROW[0]==0)) ) THEN GOTO Label_14;
    SUROWALGOVERSION[5..4] = UROW[24..23];
    SUROWALGOVERSION[6] = 1;
    Label_14:
    SUROWCHECKSUM[15..0] = UROW[127..112];
    SUROWCYCLECOUNT = INT(UROW[111..102]);
    SUROWDESIGNNAME[69..0] = UROW[101..32];
    SUROWPROGMETHOD[2..0] = UROW[31..29];
    SUROWALGOVERSION[3..0] = UROW[28..25];
    SUROW_PKG_TYPE[5..0] = UROW[22..17];
    SUROW_SW_VERSION[6..0] = UROW[16..10];
    SUROWPROGRAMSW[3..0] = UROW[9..6];
    SUROW_SRAM_DISTURB[0] = UROW[4];
    SUROW_SPEED_GRADE[2..0] = UROW[3..1];
    ACT_UROW_CYCLE_COUNT = SUROWCYCLECOUNT;
ENDPROC;

PROCEDURE FIX_INT_ARRAYS USES GV,ECCCHECK;
    IF ( ! (HEX[0]!=48) ) THEN GOTO Label_15;
    FOR I = 0 TO 7;
        TEMP = HEX[I];
        HEX[I] = HEX[(15-I)];
        HEX[(15-I)] = TEMP;
    NEXT I;
    FOR I = 0 TO 127;
        TEMP = SYNDROMETABLE[I];
        SYNDROMETABLE[I] = SYNDROMETABLE[(255-I)];
        SYNDROMETABLE[(255-I)] = TEMP;
    NEXT I;
    Label_15:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE DISP_CHKSUM_DESIGN USES GV,FIX_INT_ARRAYS;
    CALL FIX_INT_ARRAYS;
    PRINT "CHECKSUM: ",CHR$(HEX[INT(SUROWCHECKSUM[15..12])]),CHR$(HEX[INT(SUROWCHECKSUM[11..8])])
        ,CHR$(HEX[INT(SUROWCHECKSUM[7..4])]),CHR$(HEX[INT(SUROWCHECKSUM[3..0])]);
    PRINT "Design Name: ",CHR$(INT(SUROWDESIGNNAME[63..69])),CHR$(INT(SUROWDESIGNNAME[56..62]))
        ,CHR$(INT(SUROWDESIGNNAME[49..55])),CHR$(INT(SUROWDESIGNNAME[42..48])),CHR$(INT(SUROWDESIGNNAME[35..41]))
        ,CHR$(INT(SUROWDESIGNNAME[28..34])),CHR$(INT(SUROWDESIGNNAME[21..27])),CHR$(INT(SUROWDESIGNNAME[14..20]))
        ,CHR$(INT(SUROWDESIGNNAME[7..13])),CHR$(INT(SUROWDESIGNNAME[0..6]));
ENDPROC;

PROCEDURE DISPLAY_UROW USES CONSTBLOCK,GV,DISP_CHKSUM_DESIGN;
    PRINT "User information: ";
    CALL DISP_CHKSUM_DESIGN;
    IF ( ! (FLAGDISPLAYCYC==1) ) THEN GOTO Label_16;
    PRINT "CYCLE COUNT: ",SUROWCYCLECOUNT;
    Label_16:
    INTEGER TMPINT =INT(SUROWPROGMETHOD[]);
    INTEGER TMPINT2 =0;
    INTEGER TMPINT3 =0;
    INTEGER TMPINT4 =0;
    INTEGER TMPINT5 =0;
    IF ( ! (TMPINT==IEEE1532) ) THEN GOTO Label_17;
    PRINT "Programming Method: IEEE1532";
    Label_17:
    IF ( ! (TMPINT==STAPL) ) THEN GOTO Label_18;
    PRINT "Programming Method: STAPL";
    Label_18:
    IF ( ! (TMPINT==DIRECTC) ) THEN GOTO Label_19;
    PRINT "Programming Method: DirectC";
    Label_19:
    IF ( ! (TMPINT==PDB) ) THEN GOTO Label_20;
    PRINT "Programming Method: PDB";
    Label_20:
    IF ( ! (TMPINT==SVF) ) THEN GOTO Label_21;
    PRINT "Programming Method: SVF";
    Label_21:
    PRINT "Algorithm Version: ",INT(SUROWALGOVERSION[6..0]);
    TMPINT = INT(SUROW_PKG_TYPE[]);
    IF ( ! (TMPINT==UNSPECIFIED) ) THEN GOTO Label_22;
    PRINT "Device Package Type: package information not available from device";
    Label_22:
    IF ( ! (TMPINT==QN132) ) THEN GOTO Label_23;
    PRINT "Device Package Type: QN132/QNG132";
    Label_23:
    IF ( ! (TMPINT==VQ100) ) THEN GOTO Label_24;
    PRINT "Device Package Type: VQ100/VQG100";
    Label_24:
    IF ( ! (TMPINT==TQ144) ) THEN GOTO Label_25;
    PRINT "Device Package Type: TQ144/TQG144";
    Label_25:
    IF ( ! (TMPINT==PQ208) ) THEN GOTO Label_26;
    PRINT "Device Package Type: PQ208/PQG208";
    Label_26:
    IF ( ! (TMPINT==FG144) ) THEN GOTO Label_27;
    PRINT "Device Package Type: FG144/FGG144";
    Label_27:
    IF ( ! (TMPINT==FG256) ) THEN GOTO Label_28;
    PRINT "Device Package Type: FG256/FGG256";
    Label_28:
    IF ( ! (TMPINT==FG484) ) THEN GOTO Label_29;
    PRINT "Device Package Type: FG484/FGG484";
    Label_29:
    IF ( ! (TMPINT==FG676) ) THEN GOTO Label_30;
    PRINT "Device Package Type: FG676/FGG676";
    Label_30:
    IF ( ! (TMPINT==FG896) ) THEN GOTO Label_31;
    PRINT "Device Package Type: FG896/FGG896";
    Label_31:
    IF ( ! (TMPINT==QN108) ) THEN GOTO Label_32;
    PRINT "Device Package Type: QN108/QNG108";
    Label_32:
    IF ( ! (TMPINT==QN180) ) THEN GOTO Label_33;
    PRINT "Device Package Type: QN180/QNG180";
    Label_33:
    IF ( ! (TMPINT==TQ100) ) THEN GOTO Label_34;
    PRINT "Device Package Type: TQ100/TQG100";
    Label_34:
    IF ( ! (TMPINT==CQ208) ) THEN GOTO Label_35;
    PRINT "Device Package Type: CQ208/CQG208";
    Label_35:
    IF ( ! (TMPINT==FG1152) ) THEN GOTO Label_36;
    PRINT "Device Package Type: FG1152/FGG1152";
    Label_36:
    IF ( ! (TMPINT==BG456) ) THEN GOTO Label_37;
    PRINT "Device Package Type: BG456/BGG456";
    Label_37:
    IF ( ! (TMPINT==UNDEFINED) ) THEN GOTO Label_38;
    PRINT "Device Package Type: package information not available from device";
    Label_38:
    TMPINT = INT(SUROW_SPEED_GRADE[]);
    IF ( ! (TMPINT==GRADE_UNSPEC) ) THEN GOTO Label_39;
    PRINT "Device Speed Grade: speed grade information not available from device";
    Label_39:
    IF ( ! (TMPINT==GRADE_1) ) THEN GOTO Label_40;
    PRINT "Device Speed Grade: -1";
    Label_40:
    IF ( ! (TMPINT==GRADE_2) ) THEN GOTO Label_41;
    PRINT "Device Speed Grade: -2";
    Label_41:
    IF ( ! (TMPINT==GRADE_3) ) THEN GOTO Label_42;
    PRINT "Device Speed Grade: -3";
    Label_42:
    IF ( ! (TMPINT==GRADE_F) ) THEN GOTO Label_43;
    PRINT "Device Speed Grade: -F";
    Label_43:
    IF ( ! (TMPINT==GRADE_STD) ) THEN GOTO Label_44;
    PRINT "Device Speed Grade: STD";
    Label_44:
    IF ( ! (TMPINT==GRADE_4) ) THEN GOTO Label_45;
    PRINT "Device Speed Grade: -4";
    Label_45:
    IF ( ! (TMPINT==GRADE_UNDEF) ) THEN GOTO Label_46;
    PRINT "Device Speed Grade: speed grade information not available from device";
    Label_46:
    TMPINT = INT(SUROWPROGRAMSW[]);
    IF ( ! (TMPINT==FP) ) THEN GOTO Label_47;
    PRINT "Programmer: FlashPro";
    Label_47:
    IF ( ! (TMPINT==FPLITE) ) THEN GOTO Label_48;
    PRINT "Programmer: FlashPro Lite";
    Label_48:
    IF ( ! (TMPINT==FP3) ) THEN GOTO Label_49;
    PRINT "Programmer: FlashPro3";
    Label_49:
    IF ( ! (TMPINT==SCULPTW) ) THEN GOTO Label_50;
    PRINT "Programmer: SiliconSculptor II";
    Label_50:
    IF ( ! (TMPINT==BPW) ) THEN GOTO Label_51;
    PRINT "Programmer: BP Programmer";
    Label_51:
    IF ( ! (TMPINT==DIRECTCP) ) THEN GOTO Label_52;
    PRINT "Programmer: DirectC";
    Label_52:
    IF ( ! (TMPINT==STP) ) THEN GOTO Label_53;
    PRINT "Programmer: Actel JAM Player";
    Label_53:
    IF ( ! ( ( (TMPINT==FP)||(TMPINT==FPLITE))||(TMPINT==FP3)) ) THEN GOTO Label_65;
    TMPINT2 = INT(SUROW_SW_VERSION[]);
    IF ( ! (TMPINT2==FP33) ) THEN GOTO Label_54;
    PRINT "Software: FlashPro v3.3";
    Label_54:
    IF ( ! (TMPINT2==FP34) ) THEN GOTO Label_55;
    PRINT "Software: FlashPro v3.4";
    Label_55:
    IF ( ! (TMPINT2==FP40) ) THEN GOTO Label_56;
    PRINT "Software: FlashPro v4.0";
    Label_56:
    IF ( ! (TMPINT2==FP41) ) THEN GOTO Label_57;
    PRINT "Software: FlashPro v4.1";
    Label_57:
    IF ( ! (TMPINT2==FP42) ) THEN GOTO Label_58;
    PRINT "Software: FlashPro v4.2";
    Label_58:
    IF ( ! (TMPINT2==FP50) ) THEN GOTO Label_59;
    PRINT "Software: FlashPro v5.0";
    Label_59:
    IF ( ! (TMPINT2==FP51) ) THEN GOTO Label_60;
    PRINT "Software: FlashPro v5.1";
    Label_60:
    IF ( ! (TMPINT2==FP60) ) THEN GOTO Label_61;
    PRINT "Software: FlashPro v6.0";
    Label_61:
    IF ( ! (TMPINT2==FP61) ) THEN GOTO Label_62;
    PRINT "Software: FlashPro v6.1";
    Label_62:
    IF ( ! (TMPINT2==FP62) ) THEN GOTO Label_63;
    PRINT "Software: FlashPro v6.2";
    Label_63:
    IF ( ! (TMPINT2==UNKNOWN) ) THEN GOTO Label_64;
    PRINT "Software: FlashPro vX.X";
    Label_64:
    LABEL_SEPARATOR = 0;
    Label_65:
    IF ( ! ( (TMPINT==SCULPTW)||(TMPINT==BPW)) ) THEN GOTO Label_69;
    TMPINT3 = (INT(SUROW_SW_VERSION[6..5])+SCULPTORMAJORBASE);
    TMPINT4 = (INT(SUROW_SW_VERSION[4..1])+SCULPTORMINORBASE);
    TMPINT5 = 0;
    IF ( ! (SUROW_SW_VERSION[0]==1) ) THEN GOTO Label_66;
    TMPINT5 = 1;
    Label_66:
    IF ( ! (TMPINT==SCULPTW) ) THEN GOTO Label_67;
    PRINT "Software: Sculptor Win v",TMPINT3,".",TMPINT4,".",TMPINT5;
    Label_67:
    IF ( ! (TMPINT==BPW) ) THEN GOTO Label_68;
    PRINT "Software: BP Win v",TMPINT3,".",TMPINT4,".",TMPINT5;
    Label_68:
    LABEL_SEPARATOR = 0;
    Label_69:
    PRINT "=========================================";
ENDPROC;

PROCEDURE CAL_PARITY USES GV,ECCCHECK;
    INTEGER COUNT =0;
    INTEGER II;
    FOR II = 0 TO 119;
        IF ( ! ( TEMPDATA[II]&&TEMPECCSTR[II]) ) THEN GOTO Label_70;
        COUNT = (COUNT+1);
        Label_70:
        LABEL_SEPARATOR = 0;
    NEXT II;
    IF ( ! ((COUNT%2)==1) ) THEN GOTO Label_71;
    TEMPPARITY = 1;
    Label_71:
    IF ( ! ((COUNT%2)==0) ) THEN GOTO Label_72;
    TEMPPARITY = 0;
    Label_72:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE CAL_ECC USES ECCCHECK,CAL_PARITY;
    TEMPECCSTR[] = ECCSTR0[];
    CALL CAL_PARITY;
    TEMPECC[0] = TEMPPARITY;
    TEMPECCSTR[] = ECCSTR1[];
    CALL CAL_PARITY;
    TEMPECC[1] = TEMPPARITY;
    TEMPECCSTR[] = ECCSTR2[];
    CALL CAL_PARITY;
    TEMPECC[2] = ( !TEMPPARITY);
    TEMPECCSTR[] = ECCSTR3[];
    CALL CAL_PARITY;
    TEMPECC[3] = ( !TEMPPARITY);
    TEMPECCSTR[] = ECCSTR4[];
    CALL CAL_PARITY;
    TEMPECC[4] = TEMPPARITY;
    TEMPECCSTR[] = ECCSTR5[];
    CALL CAL_PARITY;
    TEMPECC[5] = TEMPPARITY;
    TEMPECCSTR[] = ECCSTR6[];
    CALL CAL_PARITY;
    TEMPECC[6] = TEMPPARITY;
    TEMPECCSTR[] = ECCSTR7[];
    CALL CAL_PARITY;
    TEMPECC[7] = TEMPPARITY;
ENDPROC;

PROCEDURE ECC1_CHECKING USES GV,ECCCHECK,CAL_ECC;
    BOOLEAN READECC[8];
    BOOLEAN CALECC[8];
    BOOLEAN SYNDROME[8];
    INTEGER IERRORBIT;
    BOOLEAN BECC1VALUE;
    READECC[7..0] = BUFF128[7..0];
    TEMPDATA[119..0] = BUFF128[127..8];
    CALL CAL_ECC;
    CALECC[] = TEMPECC[];
    FOR I = 0 TO 7;
        IF ( ! (CALECC[I]!=READECC[I]) ) THEN GOTO Label_73;
        SYNDROME[I] = 1;
        Label_73:
        LABEL_SEPARATOR = 0;
    NEXT I;
    IERRORBIT = SYNDROMETABLE[INT(SYNDROME[])];
    IF ( ! ( (IERRORBIT!=-1)&&(IERRORBIT!=-99)) ) THEN GOTO Label_76;
    BECC1VALUE = BUFF128[(8+IERRORBIT)];
    IF ( ! (BECC1VALUE==1) ) THEN GOTO Label_74;
    BUFF128[(8+IERRORBIT)] = 0;
    Label_74:
    IF ( ! (BECC1VALUE==0) ) THEN GOTO Label_75;
    BUFF128[(8+IERRORBIT)] = 1;
    Label_75:
    LABEL_SEPARATOR = 0;
    Label_76:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE READ_F_ROW USES GV,ECC1_CHECKING;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $c0;
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $f9;
    DRSCAN 3, FADDR[];
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $bf;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 264 USEC;
    DRSCAN 128, $00000000000000000000000000000000, CAPTURE BUFF128[];
    CALL ECC1_CHECKING;
ENDPROC;

PROCEDURE DO_DEVICE_INFO USES GV,READ_UROW,DISPLAY_UROW,READ_F_ROW;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $0e;
    WAIT IDLE, 1 CYCLES;
    DRSCAN 32, $00000000, CAPTURE BUFF32[];
    EXPORT "SILSIG", BUFF32[];
    CALL READ_UROW;
    CALL DISPLAY_UROW;
    FADDR[] = $0;
    CALL READ_F_ROW;
    EXPORT "FSN", BUFF128[55..8];
    PRINT "=========================================";
ENDPROC;

PROCEDURE INIT_AES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $dd;
    DRSCAN 128, $00000000000000000000000000000000;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 120 USEC;
ENDPROC;

PROCEDURE DO_VERIFY_DEVICE_INFO USES GV,BITSTREAM,DO_EXIT,DO_READ_SECURITY,READ_UROW
    ,DISP_CHKSUM_DESIGN;
    CALL READ_UROW;
    CALL DISP_CHKSUM_DESIGN;
    CALL DO_READ_SECURITY;
    BUFF32[31..0] = BOOL(CHECKSUM);
    UROW[127..112] = BUFF32[15..0];
    UROW[101..32] = ACT_UROW_DESIGN_NAME[69..0];
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $c0;
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $a8;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 264 USEC;
    DRSCAN 128, $00000000000000000000000000000000,COMPARE UROW[],$ffff003fffffffffffffffff00000000
        ,PASS;
    IF ( ! (PASS==0) ) THEN GOTO UROW_CMP_OK;
    STATUS = -43;
    PRINT "UROW setting error.";
    CALL DO_EXIT;
    UROW_CMP_OK:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE READ_IDCODE_ONLY USES GV;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $0f;
    WAIT IDLE, 1 CYCLES;
    DRSCAN 32, $00000000, CAPTURE ID[];
    EXPORT "IDCODE", ID[];
ENDPROC;

PROCEDURE VERIFY_ID_DMK USES GV,DO_EXIT,INIT_AES;
    CALL INIT_AES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $0a;
    DRSCAN 128, $e137623a2eeee91126015f3f73664945;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 256 USEC;
    DRSCAN 128, $00000000000000000000000000000000, CAPTURE BUFF128[],COMPARE $c0000000000000000000000000000000
        ,$c0000000000000000000000000000000,PASS;
    IF ( ! (BUFF128[127]==0) ) THEN GOTO M7VERDONE;
    STATUS = -31;
    PRINT "Failed to verify AES Sec.";
    CALL DO_EXIT;
    M7VERDONE:
    IF ( ! ( (BUFF128[126]==0)||(BM7DEVICE==0)) ) THEN GOTO MXIDOK;
    IF ( ! ( (BUFF128[126]==1)&&(BM7DEVICE==0)) ) THEN GOTO LDETECTM1;
    STATUS = -32;
    PRINT "Failed to verify IDCODE.";
    PRINT "M7 Device detected.";
    CALL DO_EXIT;
    LDETECTM1:
    IF ( ! (BUFF128[126]==0) ) THEN GOTO Label_79;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $0a;
    DRSCAN 128, $acdd6548ccb488863e291eb18fe95077;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 256 USEC;
    DRSCAN 128, $00000000000000000000000000000000, CAPTURE BUFF128[],COMPARE $c0000000000000000000000000000000
        ,$c0000000000000000000000000000000,PASS;
    IF ( ! (BUFF128[127]==0) ) THEN GOTO M1VERDONE;
    STATUS = -31;
    PRINT "Failed to verify AES Sec.";
    CALL DO_EXIT;
    M1VERDONE:
    BOOLEAN BTMPBUFFBIT126 = BUFF128[126];
    IF ( ! ( (BTMPBUFFBIT126==1)&&(BM1DEVICE==0)) ) THEN GOTO REGDEV;
    STATUS = -32;
    PRINT "Failed to verify IDCODE.";
    PRINT "M1 Device detected.";
    CALL DO_EXIT;
    REGDEV:
    IF ( ! ( (BTMPBUFFBIT126==0)&&(BM7DEVICE==1)) ) THEN GOTO Label_77;
    STATUS = -32;
    PRINT "Failed to verify IDCODE.";
    PRINT "The Target is not an M7 Device.";
    CALL DO_EXIT;
    Label_77:
    IF ( ! ( (BTMPBUFFBIT126==0)&&(BM1DEVICE==1)) ) THEN GOTO Label_78;
    STATUS = -32;
    PRINT "Failed to verify IDCODE.";
    PRINT "The Target is not an M1 Device.";
    CALL DO_EXIT;
    Label_78:
    LABEL_SEPARATOR = 0;
    Label_79:
    LABEL_SEPARATOR = 0;
    MXIDOK:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE VERIFY_IDCODE USES GV,PARAMETERS,DO_EXIT,VERIFY_ID_DMK;
    FREQUENCY (FREQ*1000000);
    WAIT RESET, 5 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $0f;
    DRSCAN 32, $00000000;
    WAIT IDLE, 1 CYCLES;
    DRSCAN 32, $00000000, CAPTURE ID[],COMPARE IDCODEVALUE[],IDMASK[],PASS;
    IF ( ! (PASS==0) ) THEN GOTO IDOK;
    STATUS = 6;
    PRINT "Failed to verify IDCODE";
    CALL DO_EXIT;
    IDOK:
    CALL VERIFY_ID_DMK;
    IDREV = INT(ID[31..28]);
    IDFAB = INT(ID[24..24]);
ENDPROC;

PROCEDURE IS_SECOK USES GV,DO_EXIT;
    IF ( ! (SECKEY_OK==0) ) THEN GOTO SECOK;
    STATUS = -35;
    PRINT "Error, pass key match failure";
    CALL DO_EXIT;
    SECOK:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE DO_CHECK_NVM_0_W USES GV,DO_EXIT,DO_READ_SECURITY;
    CALL DO_READ_SECURITY;
    IF ( ! (ULNW0==1) ) THEN GOTO Label_80;
    STATUS = -48;
    PRINT "NVM block 0 Write is protected by pass key.";
    PRINT "A valid pass key needs to be provided.";
    CALL DO_EXIT;
    Label_80:
    IF ( ! (ULNC0==1) ) THEN GOTO Label_81;
    STATUS = -47;
    PRINT "NVM block 0 Encryption is enforced. Plain text programming is prohibited.";
    CALL DO_EXIT;
    Label_81:
    IF ( ! (ULNR0==1) ) THEN GOTO Label_82;
    STATUS = -46;
    PRINT "NVM block 0 Read is protected by pass key.";
    PRINT "A valid pass key needs to be provided.";
    CALL DO_EXIT;
    Label_82:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE DO_CHECK_NVM_0_R USES GV,DO_EXIT,DO_READ_SECURITY;
    CALL DO_READ_SECURITY;
    IF ( ! (ULNR0==1) ) THEN GOTO Label_83;
    STATUS = -46;
    PRINT "NVM block 0 Read is protected by pass key.";
    PRINT "A valid pass key needs to be provided.";
    CALL DO_EXIT;
    Label_83:
    IF ( ! ( (ULUPC==1)&&(ULNR0==0)) ) THEN GOTO Label_84;
    CHKSEC = 0;
    Label_84:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE BP_VER USES GV;
    BOOLEAN PLAYER_VERSION_BOOLEAN[32];
    PLAYER_VERSION_BOOLEAN[31..0] = BOOL(PLAYERVERSIONVARIABLE);
    INTEGER PLAYER_MAJOR_VERSION =(INT(PLAYER_VERSION_BOOLEAN[23..16])-SCULPTORMAJORBASE);
    INTEGER PLAYER_MINOR_VERSION =(INT(PLAYER_VERSION_BOOLEAN[15..8])-SCULPTORMINORBASE);
    ACT_UROW_SW_VERSION[6..5] = BOOL(PLAYER_MAJOR_VERSION);
    ACT_UROW_SW_VERSION[4..1] = BOOL(PLAYER_MINOR_VERSION);
    ACT_UROW_SW_VERSION[0] = PLAYER_VERSION_BOOLEAN[0];
ENDPROC;

PROCEDURE DO_INITIALIZE USES GV,ECCCHECK,DO_EXIT,READ_F_ROW,VERIFY_IDCODE,DO_CHECK_NVM_0_W
    ,DO_CHECK_NVM_0_R,BP_VER;
    CALL VERIFY_IDCODE;
    BOOLEAN BSR[1056];
    BOOLEAN SAMPLE_DEVICE[1056];
    BSR[1055..0] = BSRPATTERN[1055..0];
    BOOLEAN SHIFT_DATA[1056];
    IRSCAN 8, $01;
    DRSCAN 1056, BSR[];
    WAIT IDLE, 1 CYCLES;
    DRSCAN 1056, SHIFT_DATA[], CAPTURE SAMPLE_DEVICE[];
    FOR I = 0 TO 1055;
        IF ( ! (SAMPLEMASK[I]==1) ) THEN GOTO Label_85;
        BSR[I] = SAMPLE_DEVICE[I];
        Label_85:
        LABEL_SEPARATOR = 0;
    NEXT I;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $01;
    DRSCAN 1056, BSR[];
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $c0;
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $80;
    DRSCAN 18, $00000;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 1000 USEC;
    DRSCAN 18, $00000,COMPARE $30000,$30000,PASS;
    IF ( ! (PASS==0) ) THEN GOTO CRCOK;
    STATUS = -26;
    PRINT "Failed to enter programming mode.";
    EXPORT "ISC_Config_Result", ISC_CONFIG_RESULT[];
    CALL DO_EXIT;
    CRCOK:
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $84;
    DRSCAN 5, INITIALIZE_DATA[], CAPTURE INITIALIZE_DATA[];
    WAIT IDLE, 1 CYCLES;
    IF ( ! (INITIALIZE_DATA[2]==1) ) THEN GOTO JTAGOK;
    STATUS = -25;
    PRINT "Failed to enter programming mode";
    CALL DO_EXIT;
    JTAGOK:
    IF ( ! (CHKNVM==1) ) THEN GOTO Label_88;
    IF ( ! (NVM0RONLY==0) ) THEN GOTO Label_86;
    CALL DO_CHECK_NVM_0_W;
    Label_86:
    IF ( ! (NVM0RONLY==1) ) THEN GOTO Label_87;
    CALL DO_CHECK_NVM_0_R;
    Label_87:
    LABEL_SEPARATOR = 0;
    Label_88:
    IF ( ! (PLAYERVERSIONVARIABLE!=0) ) THEN GOTO Label_89;
    CALL BP_VER;
    Label_89:
    FADDR[] = $0;
    CALL READ_F_ROW;
    ISMARTERASE = INT(BUFF128[54..52]);
    FADDR[] = $5;
    CALL READ_F_ROW;
    ISEITERATION = INT(BUFF128[120..113]);
ENDPROC;

PROCEDURE READ_INITIALIZE USES GV,DO_INITIALIZE;
    CHKFROM = 0;
    CHKARRAY = 0;
    CHKNVM = 0;
    CHKSEC = 0;
    CALL DO_INITIALIZE;
ENDPROC;

PROCEDURE NW_INITIALIZE USES GV,DO_INITIALIZE;
    CHKNVM = 1;
    NVM0RONLY = 0;
    CHKFROM = 0;
    CHKARRAY = 0;
    CALL DO_INITIALIZE;
ENDPROC;

PROCEDURE NR_INITIALIZE USES GV,DO_INITIALIZE;
    CHKNVM = 1;
    NVM0RONLY = 1;
    CHKFROM = 0;
    CHKARRAY = 0;
    CALL DO_INITIALIZE;
ENDPROC;

PROCEDURE R_INITIALIZE USES GV,DO_INITIALIZE;
    CHKNVM = 1;
    NVM0RONLY = 1;
    CALL DO_INITIALIZE;
ENDPROC;

PROCEDURE INITIALIZE USES GV,DO_INITIALIZE;
    ARRAYRONLY = 0;
    FROMRONLY = 0;
    NVM0RONLY = 1;
    CHKFROM = 1;
    CHKARRAY = 1;
    CHKNVM = 1;
    CALL DO_INITIALIZE;
ENDPROC;

PROCEDURE POLL_ERASE USES GV;
    PASS = 0;
    INTEGER ILOOP_0;
    FOR ILOOP_0 = 262141 - 1 TO 0 STEP -1;
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $84;
        WAIT IDLE, 1 CYCLES;
        WAIT IDLE, 1000 USEC;
        DRSCAN 5, $00,COMPARE $00,$03,PASS;
        IF PASS THEN ILOOP_0 = 0;
    NEXT ILOOP_0;
ENDPROC;

PROCEDURE POLL_PROGRAM USES GV;
    INTEGER ILOOP_1;
    FOR ILOOP_1 = 16381 - 1 TO 0 STEP -1;
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $84;
        WAIT IDLE, 1 CYCLES;
        WAIT IDLE, 100 USEC;
        DRSCAN 5, $00,COMPARE $00,$0b,PASS;
        IF PASS THEN ILOOP_1 = 0;
    NEXT ILOOP_1;
ENDPROC;

PROCEDURE PROGRAM_UROW USES GV,BITSTREAM,DO_EXIT,POLL_PROGRAM;
    FOR FROMROWNUMBER = NUMBEROFFROMROWS TO 1 STEP -1;
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $9f;
        DRSCAN 3, BOOL((FROMROWNUMBER-1));
        WAIT IDLE, 1 CYCLES;
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $9b;
        DRSCAN 128, $ffffffffffffffffffffffffffffffff;
        WAIT IDLE, 5 CYCLES;
        WAIT IDLE, 10000 USEC;
    NEXT FROMROWNUMBER;
    IF ( ! (ISERASEONLY==0) ) THEN GOTO SKIP_CYC_INCREMENT;
    IF ( ! (ACT_UROW_CYCLE_COUNT==1023) ) THEN GOTO Label_90;
    ACT_UROW_CYCLE_COUNT = (ACT_UROW_CYCLE_COUNT+1);
    Label_90:
    LABEL_SEPARATOR = 0;
    SKIP_CYC_INCREMENT:
    IF ( ! (ISERASEONLY==1) ) THEN GOTO Label_91;
    UROW[] = $ffffffffffffffffffffffffffffffff;
    Label_91:
    IF ( ! ( (PERMLOCK==1)&&(ULAWE==1)) ) THEN GOTO Label_92;
    ISRESTOREDESIGN = 1;
    Label_92:
    IF ( ! ( (ISERASEONLY==0)||(ISRESTOREDESIGN==1)) ) THEN GOTO SKIP_DESIGN_INFO;
    BUFF32[31..0] = BOOL(CHECKSUM);
    IF ( ! ( !ISRESTOREDESIGN) ) THEN GOTO Label_93;
    UROW[127..112] = BUFF32[15..0];
    Label_93:
    IF ( ! ISRESTOREDESIGN ) THEN GOTO Label_94;
    UROW[127..112] = SUROWCHECKSUM[15..0];
    Label_94:
    IF ( ! ( !ISRESTOREDESIGN) ) THEN GOTO Label_95;
    UROW[101..32] = ACT_UROW_DESIGN_NAME[69..0];
    Label_95:
    IF ( ! ISRESTOREDESIGN ) THEN GOTO Label_96;
    UROW[101..32] = SUROWDESIGNNAME[69..0];
    Label_96:
    LABEL_SEPARATOR = 0;
    SKIP_DESIGN_INFO:
    BUFF32[31..0] = BOOL(ACT_UROW_CYCLE_COUNT);
    UROW[111..102] = BUFF32[9..0];
    UROW[31..29] = ACT_UROW_PROG_METHOD[2..0];
    UROW[28..25] = ACT_UROW_ALGO_VERSION[3..0];
    UROW[16..10] = ACT_UROW_SW_VERSION[6..0];
    UROW[9..6] = ACT_UROW_PROGRAM_SW[3..0];
    UROW[4] = SUROW_SRAM_DISTURB[0];
    IF ( ! (ACT_UROW_ALGO_VERSION[6]==1) ) THEN GOTO Label_97;
    UROW[5] = 1;
    UROW[0] = 0;
    UROW[24..23] = ACT_UROW_ALGO_VERSION[5..4];
    Label_97:
    IF ( ! (ACT_UROW_ALGO_VERSION[6]==0) ) THEN GOTO Label_98;
    UROW[5] = 0;
    UROW[0] = 1;
    UROW[24..23] = ACT_UROW_ALGO_VERSION[5..4];
    Label_98:
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $a7;
    DRSCAN 128, UROW[];
    WAIT IDLE, 15 CYCLES;
    CALL POLL_PROGRAM;
    IF ( ! (PASS==0) ) THEN GOTO PROGRAM_OK3;
    STATUS = -24;
    PRINT "Failed to program UROW";
    CALL DO_EXIT;
    PROGRAM_OK3:
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $c0;
    WAIT IDLE, 1 CYCLES;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $a8;
    WAIT IDLE, 3 CYCLES;
    WAIT IDLE, 264 USEC;
    DRSCAN 128, $00000000000000000000000000000000,COMPARE UROW[],UROW_MASK[],PASS;
    IF ( ! (PASS==0) ) THEN GOTO UROW_OK;
    STATUS = -24;
    PRINT "Failed to program UROW";
    CALL DO_EXIT;
    UROW_OK:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE FAIL_ERASE USES GV,DO_EXIT;
    STATUS = 8;
    PRINT "Failed Erase Operation";
    CALL DO_EXIT;
ENDPROC;

PROCEDURE ERASE_TIGHTEN USES GV,FAIL_ERASE;
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $87;
    DRSCAN 2, $2;
    WAIT IDLE, 3 CYCLES;
    FOR ROWNUMBER = (NUMBEROFMAPROWS-1) TO 0 STEP -1;
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $a0;
        DRSCAN 3, $0;
        WAIT IDLE, 3 CYCLES;
        FOR I = 0 TO 2621400;
            WAIT DRPAUSE, 10 USEC;
            IRSCAN 8, $a0;
            DRSCAN 3, $0,COMPARE $0,$1,PASS;
            IF ( ! (PASS==1) ) THEN GOTO Label_99;
            I = 2621400;
            Label_99:
            LABEL_SEPARATOR = 0;
        NEXT I;
        IF ( ! (PASS==0) ) THEN GOTO Label_100;
        CALL FAIL_ERASE;
        Label_100:
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $87;
        DRSCAN 2, $3;
        WAIT IDLE, 3 CYCLES;
    NEXT ROWNUMBER;
ENDPROC;

PROCEDURE SMART_ERASE USES GV,ECCCHECK,FAIL_ERASE,ERASE_TIGHTEN;
    BOOLEAN SESTATUS[2] = $0;
    FOR J = 0 TO ISEITERATION;
        CALL ERASE_TIGHTEN;
        IRSTOP IRPAUSE;
        DRSTOP DRPAUSE;
        IRSCAN 8, $86;
        DRSCAN 2, $0;
        WAIT IDLE, 87 CYCLES;
        DRSCAN 2, $0, CAPTURE SESTATUS[],COMPARE $0,$1,PASS;
        FOR I = 0 TO 262140;
            IRSCAN 8, $86;
            DRSCAN 2, $0, CAPTURE SESTATUS[1..0],COMPARE $0,$1,PASS;
            IF ( ! (PASS==1) ) THEN GOTO Label_101;
            I = 262140;
            Label_101:
            WAIT DRPAUSE, 2003 USEC;
        NEXT I;
        IF ( ! (PASS==0) ) THEN GOTO Label_102;
        CALL FAIL_ERASE;
        Label_102:
        IF ( ! (SESTATUS[1]==1) ) THEN GOTO Label_103;
        J = ISEITERATION;
        Label_103:
        LABEL_SEPARATOR = 0;
    NEXT J;
ENDPROC;

PROCEDURE EXE_ERASE USES BITSTREAM,GV,ECCCHECK,READ_UROW,POLL_ERASE,PROGRAM_UROW
    ,FAIL_ERASE,SMART_ERASE;
    IF ( ! (COMBERASESELECT[14]==1) ) THEN GOTO SKIPRUROW;
    CALL READ_UROW;
    EXPORT "ACTEL_SLOG_UROW", UROW[];
    SKIPRUROW:
    IRSTOP IRPAUSE;
    DRSTOP DRPAUSE;
    IRSCAN 8, $85;
    DRSCAN 23, COMBERASESELECT[];
    WAIT IDLE, 3 CYCLES;
    CALL POLL_ERASE;
    IF ( ! (PASS==0) ) THEN GOTO ERASEOK;
    CALL FAIL_ERASE;
    ERASEOK:
    IF ( ! ( (ISMARTERASE==3)&&COMBERASESELECT[0]) ) THEN GOTO Label_104;
    CALL SMART_ERASE;
    Label_104:
    IF ( ! (COMBERASESELECT[14]==1) ) THEN GOTO Label_105;
    CALL PROGRAM_UROW;
    Label_105:
    LABEL_SEPARATOR = 0;
ENDPROC;

PROCEDURE DO_ERASE_ALL USES GV,EXE_ERASE;
    IF ( ! ( (BM7DEVICE==1)||(BM1DEVICE==1)) ) THEN GOTO Label_106;
    PRINT "Erase FPGA Array and FlashROM ...";
    Label_106:
    IF ( ! ( (BM7DEVICE!=1)&&(BM1DEVICE!=1)) ) THEN GOTO Label_107;
    PRINT "Erase FPGA Array, FlashROM and Security Settings ...";
    Label_107:
    COMBERASESELECT[22..0] = $7fc00f;
    ISERASEONLY = 1;
    CALL EXE_ERASE;
ENDPROC;

PROCEDURE DO_READ_IDCODE USES READ_IDCODE_ONLY;
    WAIT RESET, 5 CYCLES;
    CALL READ_IDCODE_ONLY;
    EXIT 0;
ENDPROC;

PROCEDURE DO_PROGRAM_NVM_0 USES NVM_V,GV,DO_EXIT;
    'PRINT "Program Embedded Flash Memory Module 0....";
    NVMWORDS = (NVMDATASTREAMSIZE_0/32);
    NVMWORDCOUNT = 0;
    NVMDATAINDEX = 0;
    NVMADDRESS[] = $000000000;
    NVMADDRESS[12..11] = $2;
    NVMADDRESS[10..10] = $1;
    PROTECTION[] = $00;
    FOR PAR = 0 TO (NUMOFPART_0-1);
        NVMADDRESS[34..13] = NVMADDR_0[(((PAR+1)*22)-1)..(PAR*22)];
        PAGEADDRESS = INT(NVMADDRESS[34..21]);
        PARSIZE = INT(NVMPARSIZE_0[(((PAR+1)*32)-1)..(PAR*32)]);
        PROTECTION[4..2] = NVMPROTECT_0[(((PAR+1)*3)-1)..(PAR*3)];
        IRSCAN 8, $b8;
        DRSCAN 35, NVMADDRESS[];
        WAIT 3 CYCLES;
        WAIT 20 USEC, DRPAUSE;
        FOR NVMPOLL = 0 TO 10000;
            DRSCAN 35, NVMADDRESS[],COMPARE $000000000,$600000000,PASS;
            IF ( ! (PASS==1) ) THEN GOTO Label_108;
            NVMPOLL = 10000;
            Label_108:
            IF ( ! (PASS!=1) ) THEN GOTO Label_109;
            IRSCAN 8, $b8;
            WAIT DRPAUSE, 100 USEC, DRPAUSE;
            Label_109:
            LABEL_SEPARATOR = 0;
        NEXT NVMPOLL;
        IF ( ! (PASS==0) ) THEN GOTO NVMADDRSHIFTOK_0_1;
        PRINT "Error Programming EFM.";
        STATUS = -41;
        CALL DO_EXIT;
        NVMADDRSHIFTOK_0_1:
        FOR I = 1 TO PARSIZE;
            IRSTOP IRPAUSE;
            DRSTOP DRPAUSE;
            IRSCAN 8, $b9;
            DRSCAN 32, NVMDATA_0[(NVMDATAINDEX+31)..NVMDATAINDEX];
            WAIT IDLE, 3 CYCLES;
            NVMDATAINDEX = (NVMDATAINDEX+32);
            IF ( ! ((I%32)==0) ) THEN GOTO CONTSHIFTNVM_0;
            PAGEADDRESS = (PAGEADDRESS+1);
            IRSCAN 8, $ba;
            DRSCAN 5, PROTECTION[];
            WAIT 3 CYCLES;
            WAIT 100 USEC, DRPAUSE;
            FOR NVMPOLL = 0 TO 10000;
                DRSCAN 5, PROTECTION[], CAPTURE BUFF128[4..0],COMPARE $00,$1c,PASS;
                IF ( ! (PASS==1) ) THEN GOTO Label_110;
                NVMPOLL = 10000;
                Label_110:
                IF ( ! (PASS!=1) ) THEN GOTO Label_111;
                IRSCAN 8, $ba;
                WAIT DRPAUSE, 100 USEC, DRPAUSE;
                Label_111:
                LABEL_SEPARATOR = 0;
            NEXT NVMPOLL;
            IF ( ! (PASS==0) ) THEN GOTO CONTPROG_0;
            PRINT "Error Programming EFM.";
            PRINT "Partition : ",PAR;
            PRINT "Word: ",I;
            PRINT "Page Address : ",PAGEADDRESS;
            EXPORT "BUSY", BUFF128[4..4];
            EXPORT "PrgStat", BUFF128[3..2];
            EXPORT "NvmStat", BUFF128[1..0];
            BUFF32[31..0] = BOOL(PAGEADDRESS);
            NVMADDRESS[34..21] = BUFF32[];
            IRSTOP IRPAUSE;
            DRSTOP DRPAUSE;
            IRSCAN 8, $b8;
            DRSCAN 35, NVMADDRESS[];
            WAIT IDLE, 3 CYCLES;
            WAIT IDLE, 20 USEC;
            DRSCAN 35, $000000000, CAPTURE BUFF128[34..0];
            IF ( ! (BUFF128[0]==1) ) THEN GOTO Label_112;
            PRINT "Overwrite Protect ON";
            Label_112:
            IF ( ! (BUFF128[1]==1) ) THEN GOTO Label_113;
            PRINT "Write Protect ON";
            Label_113:
            IF ( ! (BUFF128[2]==1) ) THEN GOTO Label_114;
            PRINT "Read Protect ON";
            Label_114:
            IF ( ! (BUFF128[0]!=1) ) THEN GOTO Label_115;
            PRINT "Overwrite Protect OFF";
            Label_115:
            IF ( ! (BUFF128[1]!=1) ) THEN GOTO Label_116;
            PRINT "Write Protect OFF";
            Label_116:
            IF ( ! (BUFF128[2]!=1) ) THEN GOTO Label_117;
            PRINT "Read Protect OFF";
            Label_117:
            STATUS = -41;
            CALL DO_EXIT;
            CONTPROG_0:
            LABEL_SEPARATOR = 0;
            CONTSHIFTNVM_0:
            NVMWORDCOUNT = (NVMWORDCOUNT+1);
            EXPORT "PERCENT_DONE", ((100*NVMWORDCOUNT)/NVMWORDS);
        NEXT I;
    NEXT PAR;
ENDPROC;

PROCEDURE DO_VERIFY_NVM_0 USES NVM_V,GV,DO_EXIT;
    PRINT "Verify Embedded Flash Memory Module 0...";
    NVMWORDS = (NVMDATASTREAMSIZE_0/32);
    NVMWORDCOUNT = 0;
    NVMDATAINDEX = 0;
    NVMADDRESS[] = $000000000;
    NVMADDRESS[12..11] = $2;
    FOR PAR = 0 TO (NUMOFPART_0-1);
        NVMADDRESS[34..13] = NVMADDR_0[(((PAR+1)*22)-1)..(PAR*22)];
        PAGEADDRESS = INT(NVMADDRESS[34..21]);
        OFFSET = 0;
        PARSIZE = INT(NVMPARSIZE_0[(((PAR+1)*32)-1)..(PAR*32)]);
        FOR I = 0 TO (PARSIZE-1);
            IF ( ! ( ((I%32)==0)&&(I!=0)) ) THEN GOTO SKIPADDRNVM_0;
            PAGEADDRESS = (PAGEADDRESS+1);
            OFFSET = 0;
            FOR J = 0 TO 31;
                IRSTOP IRPAUSE;
                DRSTOP DRPAUSE;
                IRSCAN 8, $b7;
                DRSCAN 35, $000000000;
                WAIT IDLE, 3 CYCLES;
            NEXT J;
            SKIPADDRNVM_0:
            BUFF32[31..0] = BOOL(PAGEADDRESS);
            NVMADDRESS[34..21] = BUFF32[13..0];
            NVMADDRESS[20] = 0;
            NVMADDRESS[19..15] = BOOL(OFFSET);
            IRSCAN 8, $b8;
            DRSCAN 35, NVMADDRESS[];
            WAIT 3 CYCLES;
            WAIT 20 USEC, DRPAUSE;
            FOR NVMPOLL = 0 TO 10000;
                DRSCAN 35, NVMADDRESS[],COMPARE $000000000,$600000000,PASS;
                IF ( ! (PASS==1) ) THEN GOTO Label_118;
                NVMPOLL = 10000;
                Label_118:
                IF ( ! (PASS!=1) ) THEN GOTO Label_119;
                IRSCAN 8, $b8;
                WAIT DRPAUSE, 100 USEC, DRPAUSE;
                Label_119:
                LABEL_SEPARATOR = 0;
            NEXT NVMPOLL;
            IF ( ! (PASS==0) ) THEN GOTO VERIFYNVMADDRSHIFTOK_0_0;
            PRINT "Error Programming EFM.";
            STATUS = -39;
            CALL DO_EXIT;
            VERIFYNVMADDRSHIFTOK_0_0:
            BUFF128[34..0] = $000000000;
            BUFF128[31..0] = NVMDATA_0[(NVMDATAINDEX+31)..NVMDATAINDEX];
            IRSTOP IRPAUSE;
            DRSTOP DRPAUSE;
            IRSCAN 8, $b7;
            DRSCAN 35, $000000000;
            WAIT IDLE, 3 CYCLES;
            WAIT IDLE, 30 USEC;
            DRSCAN 35, $000000000, CAPTURE BUFF128[69..35],COMPARE BUFF128[34..0]
                ,$6ffffffff,PASS;
            IF ( ! (PASS==0) ) THEN GOTO READ_SUCCESSFUL_0;
            INTEGER ILOOP_2;
            FOR ILOOP_2 = 10000 - 1 TO 0 STEP -1;
                BUFF32[31..0] = BOOL(PAGEADDRESS);
                NVMADDRESS[34..21] = BUFF32[13..0];
                NVMADDRESS[20] = 0;
                NVMADDRESS[19..15] = BOOL(OFFSET);
                IRSCAN 8, $b8;
                DRSCAN 35, NVMADDRESS[];
                WAIT 3 CYCLES;
                WAIT 20 USEC, DRPAUSE;
                FOR NVMPOLL = 0 TO 10000;
                    DRSCAN 35, NVMADDRESS[],COMPARE $000000000,$600000000,PASS;
                    IF ( ! (PASS==1) ) THEN GOTO Label_120;
                    NVMPOLL = 10000;
                    Label_120:
                    IF ( ! (PASS!=1) ) THEN GOTO Label_121;
                    IRSCAN 8, $b8;
                    WAIT DRPAUSE, 100 USEC, DRPAUSE;
                    Label_121:
                    LABEL_SEPARATOR = 0;
                NEXT NVMPOLL;
                IF ( ! (PASS==0) ) THEN GOTO VERIFYNVMADDRSHIFTOK_0_1;
                PRINT "Error Programming EFM.";
                STATUS = -39;
                CALL DO_EXIT;
                VERIFYNVMADDRSHIFTOK_0_1:
                BUFF128[34..0] = $000000000;
                BUFF128[31..0] = NVMDATA_0[(NVMDATAINDEX+31)..NVMDATAINDEX];
                IRSTOP IRPAUSE;
                DRSTOP DRPAUSE;
                IRSCAN 8, $b7;
                DRSCAN 35, $000000000;
                WAIT IDLE, 3 CYCLES;
                WAIT IDLE, 300 USEC;
                DRSCAN 35, $000000000, CAPTURE BUFF128[69..35],COMPARE BUFF128[34..0]
                    ,$6ffffffff,PASS;
                IF PASS THEN ILOOP_2 = 0;
            NEXT ILOOP_2;
            READ_SUCCESSFUL_0:
            OFFSET = (OFFSET+1);
            IF ( ! (PASS==0) ) THEN GOTO CONTCOMPARENVM_0;
            PRINT "Failed NVM verificaiton.";
            EXPORT "NvmAddress", NVMADDRESS[];
            EXPORT "ExpData", BUFF128[31..0];
            EXPORT "CapData", BUFF128[66..35];
            EXPORT "CapDataStat", BUFF128[69..67];
            PRINT "Page: ",PAGEADDRESS;
            PRINT "Page Offset: ",OFFSET;
            PRINT "Word: ",I;
            STATUS = -39;
            CALL DO_EXIT;
            CONTCOMPARENVM_0:
            NVMDATAINDEX = (NVMDATAINDEX+32);
            NVMWORDCOUNT = (NVMWORDCOUNT+1);
            EXPORT "PERCENT_DONE", ((100*NVMWORDCOUNT)/NVMWORDS);
        NEXT I;
    NEXT PAR;
ENDPROC;


PROCEDURE DO_READ_CALIB_DATA USES NVM_V,GV,DO_EXIT;
    PRINT "Reading CALIB Data...";
    NVMWORDS = (NVMDATASTREAMSIZE_0/32);
    NVMWORDCOUNT = 0;
    NVMDATAINDEX = 0;
    NVMADDRESS[] = $000000000;
    NVMADDRESS[12..11] = $2;
    FOR PAR = 0 TO (NUMOFPART_0-1);
        NVMADDRESS[34..13] = NVMADDR_0[(((PAR+1)*22)-1)..(PAR*22)];
        PAGEADDRESS = INT(NVMADDRESS[34..21]);
        OFFSET = 0;
        PARSIZE = INT(NVMPARSIZE_0[(((PAR+1)*32)-1)..(PAR*32)]);
        FOR I = 0 TO (PARSIZE-1);
            IF ( ! ( ((I%32)==0)&&(I!=0)) ) THEN GOTO SKIPADDRNVM_READ;
            PAGEADDRESS = (PAGEADDRESS+1);
            OFFSET = 0;
            FOR J = 0 TO 31;
                IRSTOP IRPAUSE;
                DRSTOP DRPAUSE;
                IRSCAN 8, $b7;
                DRSCAN 35, $000000000;
                WAIT IDLE, 3 CYCLES;
            NEXT J;
            SKIPADDRNVM_READ:
            BUFF32[31..0] = BOOL(PAGEADDRESS);
            NVMADDRESS[34..21] = BUFF32[13..0];
            NVMADDRESS[20] = 0;
            NVMADDRESS[19..15] = BOOL(OFFSET);
            IRSCAN 8, $b8;
            DRSCAN 35, NVMADDRESS[];
            WAIT 3 CYCLES;
            WAIT 20 USEC, DRPAUSE;
            FOR NVMPOLL = 0 TO 10000;
                DRSCAN 35, NVMADDRESS[],COMPARE $000000000,$600000000,PASS;
                IF ( ! (PASS==1) ) THEN GOTO Label_200;
                NVMPOLL = 10000;
                Label_200:
                IF ( ! (PASS!=1) ) THEN GOTO Label_201;
                IRSCAN 8, $b8;
                WAIT DRPAUSE, 100 USEC, DRPAUSE;
                Label_201:
                LABEL_SEPARATOR = 0;
            NEXT NVMPOLL;
            IF ( ! (PASS==0) ) THEN GOTO VERIFYNVMADDRSHIFTOK_0_READ;
            PRINT "Error Programming EFM.";
            STATUS = -39;
            CALL DO_EXIT;
            VERIFYNVMADDRSHIFTOK_0_READ:
            BUFF128[34..0] = $000000000;
            BUFF128[31..0] = NVMDATA_0[(NVMDATAINDEX+31)..NVMDATAINDEX];
            IRSTOP IRPAUSE;
            DRSTOP DRPAUSE;
            'READ NVM CONTENTS
            IRSCAN 8, $b7;
            DRSCAN 35, $000000000;
            WAIT IDLE, 3 CYCLES;
            WAIT IDLE, 30 USEC;
            'SAVE NVM to DATASET1
            DRSCAN 35, $000000000, CAPTURE BUFF128[34..0];

            'Start saving CALIB DATA
            'START at address 0x106401000
            ' SAVE data to TAG_CRC DATA
            IF ( NVM0_INDEX >= 160 ) THEN GOTO FINISHED_TAG_CRC;
                'if ( NVM0_INDEX == 0 ) THEN
                '    EXPORT "TAG_CRC_START", NVMADDRESS[];
                TAG_CRC[TAG_CRC_INDEX+31..TAG_CRC_INDEX] = BUFF128[31..0];
                TAG_CRC_INDEX = TAG_CRC_INDEX + 32;
            FINISHED_TAG_CRC:
            ' SAVE data set 1
            
            'Start At address 0x106429000
            'SAVE data to DATASET1
            IF ( NVM0_INDEX >= 6560 || NVM0_INDEX <160 ) THEN GOTO FINISHED_DATASET1;
                'if ( DATASET1_INDEX == 0 ) THEN
                '    EXPORT "DATASET1_START", NVMADDRESS[];
                DATASET1[DATASET1_INDEX+31..DATASET1_INDEX] = BUFF128[31..0];
                DATASET1_INDEX = DATASET1_INDEX + 32;
                FINISHED_DATASET1:
            
            'Start At address 0x107069000
            'SAVE data to DATASET2
            if ( NVM0_INDEX >= 6880 || NVM0_INDEX < 6560 ) THEN GOTO FINISHED_DATASET2;
            'if ( DATASET2_INDEX == 0 ) THEN
            '    EXPORT "DATASET2_START", NVMADDRESS[];
            DATASET2[DATASET2_INDEX+31..DATASET2_INDEX] = BUFF128[31..0];
            'EXPORT "DATA_SET2: ", BUFF128[31..0];
            DATASET2_INDEX = DATASET2_INDEX + 32;
            FINISHED_DATASET2:
            
            'Start At address 0x1070b9000
            'SAVE data to DATASET3
            if ( NVM0_INDEX >= 8480  || NVM0_INDEX < 6880 ) THEN GOTO FINISHED_DATASET3;
            'if ( DATASET3_INDEX == 0 ) THEN
            '    EXPORT "DATASET3_START:", NVMADDRESS[];
            DATASET3[DATASET3_INDEX+31..DATASET3_INDEX] = BUFF128[31..0];
            DATASET3_INDEX = DATASET3_INDEX + 32;
            FINISHED_DATASET3:
            
            'Start At address 0x107449000
            'SAVE data to DATASET4
            if ( NVM0_INDEX >= 12960 || NVM0_INDEX < 8480 ) THEN GOTO FINISHED_DATASET4;
            'if ( DATASET4_INDEX == 0 ) THEN
            '    EXPORT "DATASET4_START:", NVMADDRESS[];
            DATASET4[DATASET4_INDEX+31..DATASET4_INDEX] = BUFF128[31..0];
            DATASET4_INDEX = DATASET4_INDEX + 32;
            FINISHED_DATASET4:
            
            'INCREMENT THE NVM0_INDEX by 32 bits
            NVM0_INDEX = NVM0_INDEX + 32;
            
            
            OFFSET = (OFFSET+1);
            IF ( ! (PASS==0) ) THEN GOTO CONTCOMPARENVM_READ;
            PRINT "Failed NVM verificaiton.";
            EXPORT "NvmAddress", NVMADDRESS[];
            EXPORT "ExpData", BUFF128[31..0];
            EXPORT "CapData", BUFF128[66..35];
            EXPORT "CapDataStat", BUFF128[69..67];
            PRINT "Page: ",PAGEADDRESS;
            PRINT "Page Offset: ",OFFSET;
            PRINT "Word: ",I;
            STATUS = -39;
            CALL DO_EXIT;
            CONTCOMPARENVM_READ:
            NVMDATAINDEX = (NVMDATAINDEX+32);
            NVMWORDCOUNT = (NVMWORDCOUNT+1);
            EXPORT "PERCENT_DONE", ((100*NVMWORDCOUNT)/NVMWORDS);
        NEXT I;
    NEXT PAR;
ENDPROC;


PROCEDURE GENERATE_CRC1 USES CALIB;
    CRC1 = 0;
    'Calculate DATASET1 CRC
    FOR I = 0 TO 6400 - 1;
        CRC1 = CRC1 * 2;
        IF ( DATASET1[I] == 1 ) THEN
            CRC1 = CRC1 + 1;
        IF ( CRC1 >= INT($10000) ) THEN
            CRC1 = CRC1 ^ INT($11021);
    NEXT I;
ENDPROC;

PROCEDURE GENERATE_CRC2 USES CALIB;
    CRC2 = 0;
    'Calculate DATASET2 CRC
    FOR I = 0 TO  320 - 1;
        CRC2 = CRC2 * 2;
        IF ( DATASET2[I] == 1 ) THEN
            CRC2 = CRC2 + 1;
        IF ( CRC2 >= INT($10000) ) THEN
            CRC2 = CRC2 ^ INT($11021);
    NEXT I;
ENDPROC;

PROCEDURE GENERATE_CRC3 USES CALIB;
    CRC3 = 0;
    'Calculate DATASET3 CRC
    FOR I = 0 to 1600 - 1;
        CRC3 = CRC3 * 2;
        IF ( DATASET3[I] == 1 ) THEN
            CRC3 = CRC3 + 1;
        IF ( CRC3 >= INT($10000) ) THEN
            CRC3 = CRC3 ^ INT($11021);
    NEXT I;
ENDPROC;

PROCEDURE GENERATE_CRC4 USES CALIB;
    CRC4 = 0;
    'Calculate DATASET4 CRC
    FOR I = 0 to 4480 - 1;
        CRC4 = CRC4 * 2;
        IF ( DATASET4[I] == 1 ) THEN
            CRC4 = CRC4 + 1;
        IF ( CRC4 >= INT($10000) ) THEN
            CRC4 = CRC4 ^ INT($11021);
    NEXT I;
ENDPROC;


PROCEDURE DO_DETECT_CALIB USES CALIB, GENERATE_CRC1, GENERATE_CRC2, GENERATE_CRC3, GENERATE_CRC4, DO_READ_CALIB_DATA;
    CALL DO_READ_CALIB_DATA;
    CALL GENERATE_CRC1;
    CALL GENERATE_CRC2;
    CALL GENERATE_CRC3;
    CALL GENERATE_CRC4;
    PRINT "TAG_INFO: ", chr$(int(TAG_CRC[7..0])), chr$(int(TAG_CRC[15..8])), " VERSION: ", int(TAG_CRC[23..16]);
    IF ( INT(TAG_CRC[63..32])   == CRC1 &&
         INT(TAG_CRC[95..64])   == CRC2 &&
         INT(TAG_CRC[127..96])  == CRC3 &&
         INT(TAG_CRC[159..128]) == CRC4 ) THEN GOTO CALIB_PART;
        IS_CALIBRATED = 0;                
        PRINT "Detected a non calibrated part";
        EXPORT "EXPECTED CRC1", TAG_CRC[63..32];
        EXPORT "ACTUAL   CRC1", BOOL(CRC1);
        EXPORT "EXPECTED CRC2", TAG_CRC[95..64];
        EXPORT "ACTUAL   CRC2", BOOL(CRC2);
        EXPORT "EXPECTED CRC3", TAG_CRC[127..96];
        EXPORT "ACTUAL   CRC3", BOOL(CRC3);
        EXPORT "EXPECTED CRC4", TAG_CRC[159..128];
        EXPORT "ACTUAL   CRC4", BOOL(CRC4);
        GOTO FINISHED_DISPLAY;
    CALIB_PART:
    IS_CALIBRATED = 1;
    PRINT "Detected a calibrated part. Cannot populate default calibration data.";
    FINISHED_DISPLAY:

ENDPROC;

PROCEDURE DO_POPULATE_CALIB USES CALIB, GENERATE_CRC1, GENERATE_CRC2, GENERATE_CRC3, GENERATE_CRC4, DO_DETECT_CALIB, DO_PROGRAM_NVM_0;
    CALL DO_DETECT_CALIB;
    IF ( IS_CALIBRATED == 1 ) THEN GOTO CALIBRATED_PART;
        PRINT "POPULATING DEVICE WITH DEFAULT CALIBRATION DATA...";
        'DATASET1[6400-1..0] = NVMDATA_0[6560-1..160];
        'DATASET2[320-1..0]  = NVMDATA_0[6880-1..6560];
        'DATASET3[1600-1..0] = NVMDATA_0[8480-1..6880];
        'DATASET4[4480-1..0] = NVMDATA_0[12960-1..8480];
        'CALL GENERATE_CRC1;
        'CALL GENERATE_CRC2;
        'CALL GENERATE_CRC3;
        'CALL GENERATE_CRC4;
        'EXPORT "ACTUAL   CRC1", BOOL(CRC1);
        'EXPORT "ACTUAL   CRC2", BOOL(CRC2);
        'EXPORT "ACTUAL   CRC3", BOOL(CRC3);
        'EXPORT "ACTUAL   CRC4", BOOL(CRC4);
        CALL DO_PROGRAM_NVM_0;
    CALIBRATED_PART:
ENDPROC;

CRC 0000;
