diff options
Diffstat (limited to 'bootloaders')
| -rw-r--r-- | bootloaders/caterina/Caterina-Leonardo.hex | 1024 | ||||
| -rwxr-xr-x | bootloaders/caterina/Caterina.c | 714 | ||||
| -rwxr-xr-x | bootloaders/caterina/Caterina.h | 99 | ||||
| -rwxr-xr-x | bootloaders/caterina/Descriptors.c | 262 | ||||
| -rwxr-xr-x | bootloaders/caterina/Descriptors.h | 139 | ||||
| -rwxr-xr-x | bootloaders/caterina/Makefile | 728 | ||||
| -rw-r--r-- | bootloaders/diskloader/DiskLoader-Leonardo.hex | 115 | ||||
| -rw-r--r-- | bootloaders/diskloader/Makefile | 105 | ||||
| -rw-r--r-- | bootloaders/diskloader/src/DiskLoader.cpp | 239 | ||||
| -rw-r--r-- | bootloaders/diskloader/src/Platform.h | 51 | ||||
| -rw-r--r-- | bootloaders/diskloader/src/USBCore.cpp | 510 | ||||
| -rw-r--r-- | bootloaders/diskloader/src/USBCore.h | 246 | ||||
| -rw-r--r-- | bootloaders/diskloader/src/USBDesc.cpp | 87 | ||||
| -rw-r--r-- | bootloaders/diskloader/src/USBDesc.h | 65 | 
14 files changed, 2966 insertions, 1418 deletions
diff --git a/bootloaders/caterina/Caterina-Leonardo.hex b/bootloaders/caterina/Caterina-Leonardo.hex new file mode 100644 index 0000000..de7b53c --- /dev/null +++ b/bootloaders/caterina/Caterina-Leonardo.hex @@ -0,0 +1,1024 @@ +:200000000C946E010C9496010C9496010C9496010C9496010C9496010C9496010C94960150 +:200020000C9496010C9496010C9410050C949B050C9496010C9496010C9496010C94960181 +:200040000C9496010C9496010C9496010C9496010C9496010C9496010C9496010C94B501C9 +:200060000C9496010C9496010C9496010C9496010C9496010C9496010C9496010C949601C8 +:200080000C9496010C9496010C9496010C9496010C9496010C9496010C9496010C949601A8 +:2000A0000C9496010C9496010C94960100000000240027002A002D003000000000002500A4 +:2000C00028002B002E003100000000002300260029002C002F00040404040403040502027D +:2000E0000202040302020202060606060606040402020204040802011040804010204080A8 +:200100004080080204018040201002011080102040400000000200080E0000030401000BB2 +:200120000000070605040100080A0B0C0D09040309042203410072006400750069006E00CD +:200140006F0020004C0065006F006E006100720064006F00180341007200640075006900CC +:200160006E006F0020004C004C004300120100020000004041233680000101020001120120 +:200180000002020000404123368000010102000100C18081C1080B00020202010009040052 +:2001A000000102020000052400100105240101010424020605240600010705810310004094 +:2001C00009040100020A000000070502024000000705830240000005010902A1010901A186 +:2001E000008501050919012903150025019503750181029501750581030501093009310943 +:20020000381581257F750895038106C0C005010906A1018502050719E029E715002501754D +:20022000019508810295017508810395067508150025650507190029658100C0090402004C +:2002400001030000000921010100012265000705840340000100000000000000002A2B2895 +:200260000000000000000000000000000000000000000000002C9EB4A0A1A2A434A6A7A553 +:20028000AE362D3738271E1F20212223242526B333B62EB7B89F8485868788898A8B8C8D58 +:2002A0008E8F909192939495969798999A9B9C9D2F3130A3AD350405060708090A0B0C0D7C +:2002C0000E0F101112131415161718191A1B1C1DAFB1B0B500004C042E072C0811241FBE36 +:2002E000CFEFDAE0DEBFCDBF11E0A0E0B1E0EEECF2E102C005900D92AC32B107D9F711E061 +:20030000ACE2B1E001C01D92AD39B107E1F712E0CCEDD2E004C02297FE010E946109C63DF0 +:20032000D107C9F70E9486030C9465090C9400008091000161E00E94530364E873E080E002 +:2003400090E00E94FD018091000160E00E9453036CE474E080E090E00E94FD010895809181 +:20036000000161E00E94B60208951F920F920FB60F9211242F933F938F939F93AF93BF93DB +:200380008091300190913101A0913201B0913301309134010196A11DB11D232F2D5F2D3794 +:2003A00020F02D570196A11DB11D209334018093300190933101A0933201B0933301809117 +:2003C0002C0190912D01A0912E01B0912F010196A11DB11D80932C0190932D01A0932E01BA +:2003E000B0932F01BF91AF919F918F913F912F910F900FBE0F901F9018959B01AC017FB734 +:20040000F89480912C0190912D01A0912E01B0912F0166B5A89B05C06F3F19F00196A11DC3 +:20042000B11D7FBFBA2FA92F982F8827860F911DA11DB11D62E0880F991FAA1FBB1F6A9577 +:20044000D1F7BC012DC0FFB7F89480912C0190912D01A0912E01B0912F01E6B5A89B05C0E7 +:20046000EF3F19F00196A11DB11DFFBFBA2FA92F982F88278E0F911DA11DB11DE2E0880FFD +:20048000991FAA1FBB1FEA95D1F7861B970B885E9340C8F2215030404040504068517C4F8F +:2004A000211531054105510571F60895789484B5826084BD84B5816084BD85B5826085BD0F +:2004C00085B5816085BDEEE6F0E0808181608083E1E8F0E010828081826080838081816043 +:2004E0008083E0E8F0E0808181608083E1EBF0E0808184608083E0EBF0E080818160808378 +:20050000E1E9F0E0808182608083808181608083E0E9F0E0808181608083E1ECF0E080815A +:2005200084608083808182608083808181608083E3ECF0E0808181608083E0ECF0E08081E8 +:2005400082608083E2ECF0E0808181608083EAE7F0E08081846080838081826080838081C3 +:20056000816080838081806880830895CF93DF93482F50E0CA018C509F4FFC0134914A52A0 +:200580005F4FFA018491882369F190E0880F991FFC01E455FF4FA591B491FC01E654FF4F55 +:2005A000C591D491662351F42FB7F8948C91932F909589238C93888189230BC0623061F40A +:2005C0002FB7F8948C91932F909589238C938881832B88832FBF06C09FB7F8948C91832BB7 +:2005E0008C939FBFDF91CF9108958730C1F1883080F48330F9F0843030F4813029F182308B +:2006000009F050C024C08430C9F0863009F04AC022C08A3091F18B3030F4883031F1893037 +:2006200009F040C026C08C3091F18C3060F18E30C9F533C0809180008F7703C08091800036 +:200640008F7D80938000089584B58F7702C084B58F7D84BD08958091B0008F7703C080919F +:20066000B0008F7D8093B0000895809190008F7707C0809190008F7D03C080919000877FD9 +:200680008093900008958091C0008F7703C08091C0008F7D8093C00008958091C200877F5A +:2006A0008093C2000895FF920F931F93F62E482F50E0CA018E5E9E4FFC012491CA018C501B +:2006C0009F4FFC0114914A525F4FFA0104910023C9F0222319F0822F0E94F502E02FF0E05D +:2006E000EE0FFF1FE654FF4FA591B4919FB7F894FF2021F48C911095812302C08C91812BD5 +:200700008C939FBF1F910F91FF900895CF93DF930E9456028DE391E00E944D040E94AF01EC +:20072000C0E0D0E00E9498012097E1F30E940000F9CF282F809137018823C1F057FF1AC00D +:2007400015C02898909336018091F1008193E217F307B9F74115510539F08091F20088236E +:2007600019F48BE68093E800AFBF02C04FEF5FEFCA010895AFB7F89427702093E9008091A6 +:20078000F200282F30E0241735070CF4A901FB019B01240F311D94E6DACFDF93CF930F922E +:2007A000CDB7DEB7BE016F5F7F4F41E050E00E949903019719F02FEF3FEF03C08981282F25 +:2007C00030E0C9010F90CF91DF910895FF920F931F93F82E142F052F40913A0150913B0188 +:2007E000212F302FC901DC01FB016EEF29C0F7FE02C0949101C090812091380130913901CE +:2008000024173507ACF48091E8008570E1F38091E80082FF03C02FEF3FEF17C09093F1008B +:20082000C90101968F739070892B11F46093E8002F5F3F4F3093390120933801119731964D +:200840001097A9F6812F902F9C01C9011F910F91FF9008959C018091E80082FFFCCFF90124 +:20086000260F311D03C08091F1008193E217F307D1F7289884E6809336018BEF8093E80078 +:20088000CB0108958093E9008091F200882319F08AE38093E800089508951092370181E05F +:2008A0008093D70080EA8093D80082E189BD09B400FEFDCF61E070E080E090E00E94FD01C8 +:2008C00080E98093D8008CE08093E2001092E000559A209A08955F926F927F928F929F9246 +:2008E000AF92BF92CF92DF92EF92FF920F931F93CF93DF93E82E842E752E809137018823FB +:2009000071F18B01242F352FC901EC017AEFF72E67E0962E9E2050E4552E8E2D90E040E220 +:20092000A42EB12CA822B9223AE3632E20E4C22ED12CC822D92258C09FB7F8949092E900DA +:200940008091E80085FD02C020E004C08091F200252D281B9FBF222361F4FA9419F42FEF4D +:200960003FEF4DC061E070E080E090E00E94FD013BC0822F90E0C817D9070CF42C2FC21B28 +:20098000D1094FB7F8949092E900A114B10421F406C01092F10021502223D9F719C0E7FCC6 +:2009A00003C0F801922F10C0C801322F06C0FC010196E491E093F10031503323C1F706C038 +:2009C00081918093F10091509923D1F7020F111D8091E80085FF05C0209729F4C114D1049D +:2009E00011F06092E8004FBF209709F0A5CF5D9884E680933501282D372DC9019C01C90158 +:200A0000DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F90089564 +:200A20001F920F920FB60F9211241F932F933F934F935F936F937F938F939F93AF93BF93B3 +:200A4000EF93FF938091E1001092E100982F83FF0FC01092E90081E08093EB001092EC007D +:200A600082E38093ED001092370188E08093F00092FF36C083E08093E9008091F200882338 +:200A800049F08AE38093E80005C082E891E00E94710701C012E09FB7F8941093E9008091C9 +:200AA000F2009FBF882389F780913501882351F08091350181508093350180913501882335 +:200AC00009F45D9A80913601882351F08091360181508093360180913601882309F4289AD9 +:200AE000FF91EF91BF91AF919F918F917F916F915F914F913F912F911F910F900FBE0F90DB +:200B00001F9018950F931F93DF93CF930F92CDB7DEB719828E010F5F1F4FC8010E9490078F +:200B2000C8010E942909898190E00F90CF91DF911F910F9108951F920F920FB60F92112455 +:200B4000EF92FF921F932F933F934F935F936F937F938F939F93AF93BF93EF93FF93DF93E7 +:200B6000CF93CDB7DEB76197DEBFCDBF1092E9008091E80083FF0FC1FE0131969E01275F18 +:200B80003F4F03C08091F1008193E217F307D1F7289884E68093360182EF8093E800998139 +:200BA00097FF05C08091E80080FFFCCF03C08EEF8093E800292F30E0C90180769070892B80 +:200BC00009F0C2C08A81882329F41092F1001092F100D6C0813009F4D3C0833009F4D0C08A +:200BE000853049F48091E80080FFFCCF8B8180688093E300C5C0863009F07CC01C81EF805A +:200C0000F8841230C1F51092E900109239011092380110923B0110923A010E94820599E0C1 +:200C2000FE013996DF01292F1D922A95E9F799871A8791E09E8790E8988B9AEF998B209110 +:200C4000380130913901275F3F4F3C872B878D871092E9001092390110923801F0923B01C3 +:200C6000E0923A0180E0BF0149E050E00E94E6030E94820585C01092E9001092390110924C +:200C80003801F0923B01E0923A01123241F482E290E00E942109892B09F476C071C011303E +:200CA00079F488E0E816F10419F481E080933C0180913C01882309F06BC0ECE6F1E013C01B +:200CC000133009F061C08B81882319F4EEE2F1E00AC0823019F4E2E3F1E005C0813009F0C4 +:200CE00053C0E4E5F1E0449180E8BF0150E00E94E60346C0873009F447C0883021F481E0A0 +:200D00008093F1003DC08930D9F523703070232BD9F5E1E9F1E091E031E026E39093E900CA +:200D20003093EB0084918093EC002093ED009F5F3196953099F78EE78093EA001092EA0039 +:200D40008B81809337011CC08F8198851092E900109239011092380190933B0180933A0144 +:200D60008D81882329F4CE0101960E949C0706C0823051F4CE0101960E94F207882321F078 +:200D80008EEF8093E80007C081E28093EB0003C0EEE7F1E0A8CF6196DEBFCDBFCF91DF91E3 +:200DA000FF91EF91BF91AF919F918F917F916F915F914F913F912F911F91FF90EF900F9076 +:200DC0000FBE0F901F90189520917E0130917F018091800190918101281B390B2F733070DC +:200DE000C901089520917E0130917F0180918001909181012817390719F42FEF3FEF09C045 +:200E0000E0918001F0918101E25CFE4F8081282F30E0C901089520917E0130917F01809101 +:200E20008001909181012817390719F42FEF3FEF13C0E0918001F0918101E25CFE4F2081C2 +:200E4000809180019091810101968F739070909381018093800130E0C901089510928501EC +:200E60001092840188EE93E0A0E0B0E08093860190938701A0938801B093890180E191E0B2 +:200E8000909383018093820108950F931F93DF93CF930F92CDB7DEB78C0169838091090102 +:200EA000882369F083E0BE016F5F7F4F41E050E00E946B041816190614F49C0107C081E0F4 +:200EC00090E0F8019383828320E030E0C9010F90CF91DF911F910F91089583E00E9442040D +:200EE000089582E00E94CD03482F20917E0130917F012F5F3F4F2F73307080918001909188 +:200F000081012817390759F0E0917E01F0917F01E25CFE4F408330937F0120937E01089536 +:200F2000FC0180818E5F808380E865E971E042E450E00E94E6030895FC0181819081913A63 +:200F400059F4813209F04CC080E062E071E047E050E00E94E60342C0913209F041C0803246 +:200F600039F482E091E067E070E00E942A0436C0823209F035C0828180930901809102013E +:200F800090910301A0910401B0910501805B9440A040B04019F58091090180FD12C087E74A +:200FA00097E790930108809300082BE088E190E00FB6F894A895809360000FBE20936000A7 +:200FC0000DC088E10FB6F89480936000109260000FBEA895109201081092000881E00895B8 +:200FE00080E00895FC0191818081813A31F4913089F080E0933089F40DC0813269F49B3082 +:2010000021F4828180930A0105C09A3029F4828180930B0181E0089580E00895EF92FF92BF +:201020000F931F938C01E62EDC01ED91FC910480F581E02D0995F82ED801ED91FC9106809E +:20104000F781E02DC8016E2D09958F2D90E01F910F91FF90EF900895109290011092940178 +:201060001092930182E291E090939201809391010895EF92FF920F931F93DF93CF930F9292 +:20108000CDB7DEB789838B017A0184E0BE016F5F7F4F41E050E00E946B0484E4B801A7013A +:2010A0000E946B040F90CF91DF911F910F91FF90EF90089582E048E050E00E94390808957B +:2010C000FC0116821782108611861286138614823496BF010E945A080895DC01683810F046 +:2010E000685829C0E62FF0E067FF13C0E058F04081E090E002C0880F991FEA95E2F7809572 +:2011000014962C911497282314962C93149760E012C0EB5AFD4F6491662319F420E030E020 +:201120001DC067FF08C014968C9114978D7F14968C9314976F77FD0190E0662321F08681BD +:20114000861709F416829F5F31969630B1F7CD011496BD010E945A0821E030E0C901089578 +:20116000CF93DF93DC01683810F0685825C0E62FF0E067FF12C0E058F04081E090E002C061 +:20118000880F991FEA95E2F714962C911497282B14962C93149760E00FC0EB5AFD4F64919A +:2011A0006623D9F167FF08C014968C911497826014968C9314976F7716968C9116978617ED +:2011C000A9F117968C911797861781F118968C911897861759F119968C911997861731F152 +:2011E0001A968C911A97861709F11B968C911B978617E1F0ED01E0E0F0E09E2F8E818823E7 +:2012000021F4EA0FFB1F668306C09F5F31962196E630F10591F7963049F481E090E013966A +:201220009C938E93129720E030E007C0CD011496BD010E945A0821E030E0C901DF91CF91F9 +:20124000089580E867ED71E045E650E00E94E6030895FC0180818F5F808380E86CE372E069 +:2012600049E150E00E94E6030895CF92DF92EF92FF920F931F93CF93DF937C016B018A016C +:20128000C0E0D0E00FC0D6016D916D01D701ED91FC910190F081E02DC7010995C80FD91FC5 +:2012A000015010400115110571F7CE01DF91CF911F910F91FF90EF90DF90CF900895EE0F94 +:2012C000FF1F0590F491E02D0994F894FFCF0D0000E1000000000000010100000000450796 +:2012E0003509E4060B07F2066D077107000000000E083509B0086D086008FFFFFFFFFFFFED +:20130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:2013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:2013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:20140000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20142000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20144000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20146000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20148000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:2014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:2014C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2014E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:20150000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20152000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20154000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20156000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20158000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:2015A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:2015C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2015E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:20160000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20162000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20164000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20166000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20168000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:2016A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:2016C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2016E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:20170000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20172000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20174000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20176000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20178000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:2017A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:2017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2017E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:20180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20182000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20184000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20186000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20188000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:2018A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:2018C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2018E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:20190000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:20192000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20194000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20196000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20198000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:2019A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:2019C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2019E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:201A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:201A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:201A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:201A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:201A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:201AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:201AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:201AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:201B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:201B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:201B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:201B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:201B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:201BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:201BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:201BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:201C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:201C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:201C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:201C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:201C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:201CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:201CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:201CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:201D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:201D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:201D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:201D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:201D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:201DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:201DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:201DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:201E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:201E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:201E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:201E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:201E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:201EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:201EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:201EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:201F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:201F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:201F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:201F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:201F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:201FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:201FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:201FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:20200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:2020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:20210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:2021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:20220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:2022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:20230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:2023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:20240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:2024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:20250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:2025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:20260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:2026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:20270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:2027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:20280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:2028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:20290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:20292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:2029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:202A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:202A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:202A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:202A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:202A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:202AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:202AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:202AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:202B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:202B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:202B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:202B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:202B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:202BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:202BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:202BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:202C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:202C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:202C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:202C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:202C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:202CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:202CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:202CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:202D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:202D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:202D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:202D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:202D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:202DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:202DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:202DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:202E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:202E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:202E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:202E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:202E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:202EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:202EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:202EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:202F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:202F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:202F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:202F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:202F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:202FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:202FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:202FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:20300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:2030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:20310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:2031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:20320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:2032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:20330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:2033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:20340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:2034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:20350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:2035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:20360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:2036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:20370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:2037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:20380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:2038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:20390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:20392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:2039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:203A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:203A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:203A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:203A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:203A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:203AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:203AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:203AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:203B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:203B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:203B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:203B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:203B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:203BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:203BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:203BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:203C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:203C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:203C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:203C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:203C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:203CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:203CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:203CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:203D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:203D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:203D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:203D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:203D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:203DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:203DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:203DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:203E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:203E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:203E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:203E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:203E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:203EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:203EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:203EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:203F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:203F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:203F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:203F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:203F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:203FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:203FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:203FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:20400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:2040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:20410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:2041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:20420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:2042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:20430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:2043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:20440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:2044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:20450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:2045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:20460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:2046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:20470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:2047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:20480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:2048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:20490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:20492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:2049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:204A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:204A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:204A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:204A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:204A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:204AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:204AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:204AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:204B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:204B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:204B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:204B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:204B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:204BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:204BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:204BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:204C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:204C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:204C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:204C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:204C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:204CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:204CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:204CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:204D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:204D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:204D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:204D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:204D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:204DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:204DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:204DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:204E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:204E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:204E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:204E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:204E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:204EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:204EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:204EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:204F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:204F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:204F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:204F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:204F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:204FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:204FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:204FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:20500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:20502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:20504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:20506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:20508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:2050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 +:2050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:2050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:20510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +:20512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +:20514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F +:20516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F +:20518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F +:2051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:2051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +:2051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +:20520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE +:20522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E +:20524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E +:20526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E +:20528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E +:2052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E +:2052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE +:2052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE +:20530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:20532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D +:20534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D +:20536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D +:20538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D +:2053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D +:2053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED +:2053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:20540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC +:20542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:20544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:20546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C +:20548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C +:2054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C +:2054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +:2054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +:20550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB +:20552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B +:20554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B +:20556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B +:20558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B +:2055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B +:2055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB +:2055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB +:20560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA +:20562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A +:20564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A +:20566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A +:20568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A +:2056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A +:2056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +:2056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA +:20570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 +:20572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 +:20574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 +:20576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 +:20578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:2057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:2057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 +:2057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:20580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:20582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 +:20584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:20586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 +:20588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 +:2058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 +:2058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:2058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 +:20590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +:20592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:20594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:20596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:20598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:2059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:2059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:2059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +:205A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 +:205A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 +:205A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:205A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 +:205A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 +:205AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 +:205AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +:205AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 +:205B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 +:205B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 +:205B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 +:205B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 +:205B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:205BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:205BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:205BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:205C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 +:205C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:205C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:205C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:205C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 +:205CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 +:205CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +:205CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 +:205D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 +:205D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 +:205D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 +:205D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:205D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 +:205DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 +:205DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 +:205DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 +:205E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 +:205E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 +:205E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 +:205E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 +:205E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:205EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:205EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:205EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:205F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 +:205F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 +:205F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 +:205F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 +:205F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 +:205FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 +:205FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +:205FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 +:20600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:20602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:20604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:20606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:20608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 +:2060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:2060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:2060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:20610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +:20612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +:20614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:20616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F +:20618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F +:2061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +:2061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +:2061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +:20620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E +:20622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E +:20624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E +:20626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E +:20628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E +:2062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +:2062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE +:2062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE +:20630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D +:20632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D +:20634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D +:20636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D +:20638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D +:2063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +:2063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD +:2063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:20640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:20642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:20644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C +:20646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C +:20648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C +:2064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC +:2064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC +:2064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC +:20650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B +:20652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B +:20654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B +:20656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B +:20658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B +:2065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +:2065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +:2065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB +:20660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A +:20662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A +:20664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A +:20666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A +:20668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A +:2066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +:2066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA +:2066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA +:20670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +:20672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 +:20674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 +:20676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 +:20678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:2067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +:2067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 +:2067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:20680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 +:20682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 +:20684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:20686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 +:20688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 +:2068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +:2068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 +:2068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 +:20690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:20692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:20694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:20696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:20698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:2069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:2069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:2069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +:206A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 +:206A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 +:206A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 +:206A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 +:206A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 +:206AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +:206AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 +:206AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 +:206B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 +:206B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +:206B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 +:206B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 +:206B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:206BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:206BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:206BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 +:206C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:206C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:206C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:206C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:206C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 +:206CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 +:206CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 +:206CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 +:206D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 +:206D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 +:206D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 +:206D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 +:206D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 +:206DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 +:206DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 +:206DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 +:206E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:206E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 +:206E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 +:206E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 +:206E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:206EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:206EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:206EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 +:206F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 +:206F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 +:206F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 +:206F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 +:206F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 +:206FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +:206FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 +:206FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 +:2070000055C000006EC000006CC000006AC0000068C0000066C0000064C0000062C0000043 +:2070200060C000005EC00000EEC400005AC0000058C0000056C0000054C0000052C00000F2 +:2070400050C0000078C000004CC000004AC0000048C0000046C0000044C0000042C00000BE +:2070600040C000003EC000003CC000003AC0000038C0000036C0000034C0000032C0000048 +:2070800030C000002EC000002CC000002AC0000028C0000026C0000024C0000022C00000A8 +:2070A00020C000001EC000001CC0000011241FBECFEFDAE0DEBFCDBF11E0A0E0B1E0EAE2B5 +:2070C000FFE702C005900D92A83AB107D9F711E0A8EAB1E001C01D92AE3BB107E1F78FD30B +:2070E00022C78ECFF89410926F0010928100109285001092840081E085BF15BE47985D9AEF +:20710000289A0C94000008952091B2013091B3012F5F3F4F3093B3012093B201932F37FFA6 +:2071200003C08EEF831B982F990F921710F447980895479A08951F920F920FB60F9211246E +:207140002F938F939F93EF93FF9310928500109284008091A8019091A901009741F00197D3 +:207160009093A9018093A801892B09F45D9A8091AA019091AB01009741F001979093AB0126 +:207180008093AA01892B09F4289AE0E0F0E0859194918F5F9F4F49F08091AC019091AD0151 +:2071A00001969093AD018093AC01FF91EF919F918F912F910F900FBE0F901F90189584E0BC +:2071C0008093E9000DC08091E8008B778093E80003C08EB3882351F08091E80082FFF9CFBE +:2071E0008091E80085FFEFCF8091F1000895982F83E08093E9008091E80085FD0DC0809136 +:20720000E8008E778093E80003C08EB3882369F08091E80080FFF9CF9093F1005D9884E6CB +:2072200090E09093A9018093A80108954F925F926F927F928F929F92AF92BF92CF92DF921E +:20724000EF92FF920F931F93CF93DF9384E08093E9008091E80082FF57C2289884E690E067 +:207260009093AB018093AA01AADF182F853481F48CE49DE19093AD018093AC0107B600FC4B +:20728000FDCFF999FECF81E180935700E89503C0843519F494DF8DE00DC28C34E1F38035F9 +:2072A000D1F3843721F484E4A2DF80E003C2813611F489E5FFC18134B1F481DF182F7FDFE3 +:2072C00090E0880F991FAA2797FDA095BA2F312F330F20E0442737FD4095542F822B932B68 +:2072E000A42BB52BB8C1803711F483E5E3C1833549F4C0E0D1E089917ADF21E0C730D20714 +:20730000D1F7D9C1863521F481E371DF80E3D2C1833731F487E86BDF85E969DF8EE1CAC149 +:207320008536B9F4E0E0F0E093E085E090935700E89507B600FCFDCF80935700E89507B65D +:2073400000FCFDCFE058FF4FA0E7E030FA0771F7A2CF823739F4E1E0F0E089E08093570024 +:207360008491A8C1863439F4E0E0F0E089E08093570084919FC18E3439F4E3E0F0E089E0E5 +:2073800080935700849196C1813539F4E2E0F0E089E08093570084918DC1823631F489E521 +:2073A00026DF80E024DF80E885C1823419F0873609F0E5C01092AD011092AC0100DF082FE8 +:2073C000FEDEF82EFCDE682E8554823008F071C1902F80E0CF2DD0E0C82BD92B10926F00B3 +:2073E000173609F04BC081E180935700E895DD24CC24C3943FC0E090AE01F090AF010091CC +:20740000B0011091B101B6E46B16D9F4ED2DF0E0EE29FF29E4918E2FEADEDD2081F082E08D +:2074200090E0A0E0B0E0E80EF91E0A1F1B1FE092AE01F092AF010093B0011093B101DC2470 +:2074400018C0D801C701B695A7959795879555D5CEDE82E090E0A0E0B0E0E80EF91E0A1FF6 +:207460001B1FE092AE01F092AF010093B0011093B1012197209709F0BECF7DC08090AE01F5 +:207480009090AF01A090B001B090B10196E4691609F05DC083E0F40180935700E89507B63E +:2074A00000FCFDCF54C0F6E46F1661F5772031F1E090AE01F090AF010091B0011091B1019E +:2074C0007EDED82ECC24852D90E08C299D29F7010C0140925700E895112482E090E0A0E08B +:2074E000B0E0E80EF91E0A1F1B1FE092AE01F092AF010093B0011093B10102C060DE582E1A +:20750000742423C0E090AE01F090AF010091B0011091B10116950795F794E79450DE682FFA +:20752000C701F3D48091AE019091AF01A091B001B091B1010296A11DB11D8093AE0190934D +:20754000AF01A093B001B093B101219704C05524772444244394209709F0A5CF96E46916B6 +:2075600041F485E0F40180935700E89507B600FCFDCF8DE03CDE82E080936F009CC0833492 +:2075800071F40091AE011091AF0119DE90E021E0F8010C0120935700E89511247CCE8336C8 +:2075A00019F5E090AE01F090AF010091B0011091B10105DEF701E16090E021E00C0120938C +:2075C0005700E895112482E090E0A0E0B0E0E80EF91E0A1F1B1FE092AE01F092AF0100936A +:2075E000B0011093B10157CE8D3661F4E091AE01F091AF0185E080935700E89507B600FCF2 +:20760000FDCF49CE823551F4E091AE01F091AF0105911491812FEBDD802F4CC0843421F5FE +:20762000E090AE01F090AF010091B0011091B10116950795F794E794C2DD682FC70165D4E2 +:207640008091AE019091AF01A091B001B091B1010296A11DB11D8093AE019093AF01A093D8 +:20766000B001B093B10117CE843609F5E090AE01F090AF010091B0011091B101D801C70142 +:20768000B695A7959795879538D4B1DD82E090E0A0E0B0E0E80EF91E0A1F1B1FE092AE010E +:2076A000F092AF010093B0011093B10104C08B3111F08FE39CDD83E08093E9009091E8002B +:2076C0008091E8008E778093E80095FF04C010C08EB38823C9F08091E80080FFF9CF809193 +:2076E000E8008E778093E80003C08EB3882361F08091E80080FFF9CF84E08093E9008091F1 +:20770000E8008B778093E800DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F90AC +:207720007F906F905F904F9008959091B601892F8F77813249F58091B7018032A1F081328A +:2077400019F5913A09F58091E800877F8093E8008DE091E067E070E007D28091E8008B770F +:207760008093E8000895913279F48091E800877F8093E8008DE091E067E070E059D2809196 +:20778000E8008E778093E800089582E061EC42E0B1D083E061E842E1ADD084E060E842E1F7 +:2077A000A9C084B7877F84BF88E10FB6F89480936000109260000FBE20E880E090E00FB643 +:2077C000F89420936100809361000FBE81E085BF92E095BF3F9A209A559AE1E6F0E02083A1 +:2077E000108247985D9A289A109289008AEF8093880090936F0083E080938100ECC040911A +:20780000000850910108109201081092000824B714BE88E10FB6F894809360001092600045 +:207820000FBE822F90E0FC01E270F07021FD14C0213019F4859194910BC0283069F480918F +:20784000090190910A014817590731F0859194918F5F9F4F09F046DCA4DF78941092AD0101 +:207860001092AC010CC0E2DC36D38091AC019091AD0181549F4110F01092140145DC8091FB +:207880001401882381F78091E00081608093E00029DC80E090E00895FA01923049F09330C0 +:2078A00061F09130F9F485E191E022E130E01EC087E291E02EE330E019C0882329F485E6FA +:2078C00091E024E030E012C0813029F489E691E022E230E00BC0823029F48DE891E028E106 +:2078E00030E004C080E090E020E030E091838083C90108958093E9008091EB00816080936A +:20790000EB001092ED006093EC004093ED008091EE00881F8827881F08958091B601882342 +:207920008CF403C08EB38823B1F08091E80082FFF9CF8091E8008B778093E80008958EB361 +:20794000882349F08091E80080FFF9CF8091E8008E778093E8000895EF92FF920F931F9307 +:2079600045D04CD008ED10E0F80180818F77808380818068808380818F7D808319BC1EBA45 +:207980001092B40180EEE82EF12CF70180818B7F8083F80180818160808380E060E042E049 +:2079A000A9DFE1EEF0E080818E7F8083E2EEF0E0808181608083808188608083F701808125 +:2079C0008E7F8083F8018081806180831F910F91FF90EF900895E7EDF0E080818160808335 +:2079E0008AE482BF81E08093B501B6CFE8EDF0E080818E7F80831092E20008951092DA00D6 +:207A00001092E10008951F920F920FB60F9211242F933F934F935F936F937F938F939F9389 +:207A2000AF93BF93EF93FF938091DA0080FF1BC08091D80080FF17C08091DA008E7F80930F +:207A4000DA008091D90080FF0BC080E189BD82E189BD09B400FEFDCF81E08EBB3BD203C0C7 +:207A600019BC1EBA37D28091E10080FF17C08091E20080FF13C08091E2008E7F8093E200CE +:207A80008091E20080618093E2008091D80080628093D80019BC85E08EBB1CD28091E10004 +:207AA00084FF2CC08091E20084FF28C080E189BD82E189BD09B400FEFDCF8091D8008F7D2D +:207AC0008093D8008091E1008F7E8093E1008091E2008F7E8093E2008091E20081608093EC +:207AE000E2008091B401882331F48091E30087FD02C081E001C084E08EBBECD18091E10056 +:207B000083FF21C08091E20083FF1DC08091E100877F8093E10082E08EBB1092B4018091B1 +:207B2000E1008E7F8093E1008091E2008E7F8093E2008091E20080618093E20080E060E005 +:207B400042E0D8DEC7D1FF91EF91BF91AF919F918F917F916F915F914F913F912F910F90B6 +:207B60000FBE0F901F9018959C014091BC015091BD014617570718F4F90190E044C06115C8 +:207B8000710511F0AB01F8CF8091E8008E778093E80040E050E0F0CF8EB3882309F444C006 +:207BA000853009F443C08091E80083FF02C081E008958091E80082FD31C08091E80080FFF4 +:207BC00022C08091F3009091F200782F60E0292F30E0262B372B07C081918093F10041503C +:207BE00050402F5F3F4F4115510519F02830310598F390E02830310509F491E08091E800A6 +:207C00008E778093E8004115510531F6992321F605C08EB3882341F0853041F08091E800FD +:207C200082FFF7CF80E0089582E0089583E008959C016115710529F48091E8008B7780934D +:207C4000E800F90126C08EB3882391F1853091F18091E80083FF02C081E008958091E80083 +:207C600082FFF1CF06C08091F10081936150704059F02091F3008091F200322F20E090E0C5 +:207C8000822B932B892B79F78091E8008B778093E80061157105B9F605C08EB3882341F0E2 +:207CA000853041F08091E80080FFF7CF80E0089582E0089583E008950F931F93DF93CF937C +:207CC00000D0CDB7DEB7E6EBF1E08091F100819381E0EE3BF807C9F728DD8091E80083FF3A +:207CE000E4C08091B6019091B701953009F46DC0963040F4913081F1913070F0933009F046 +:207D0000D4C02AC0983009F4A3C0993009F4B2C0963009F0CAC07CC0803809F4C6C082380B +:207D200009F0C3C08091BA0187708093E9008091EB001092E9002091E800277F2093E800A7 +:207D400090E025E0969587952A95E1F781708093F1001092F10087C0882319F0823009F0A2 +:207D6000A4C08F71823009F0A0C08091B801882331F52091BA01277009F497C02093E90006 +:207D80008091EB0080FF1BC0933021F48091EB00806213C08091EB0080618093EB0081E0C8 +:207DA00090E002C0880F991F2A95E2F78093EA001092EA008091EB0088608093EB0010929D +:207DC000E9008091E800877F51C0882309F06DC01091B8011F770FB7F8948091E800877F98 +:207DE0008093E8009ADD8091E80080FFFCCF8091E3008078812B8093E30080688093E30062 +:207E0000112311F482E001C083E08EBB0FBF4DC08058823008F049C08091B8019091B9014F +:207E20006091BA01AE014F5F5F4F36DDBC01009709F43BC08091E800877F8093E800898128 +:207E40009A8192DE8091E8008B778093E8002DC0803859F58091E800877F8093E8008091A3 +:207E6000B4018093F1008091E8008E778093E80054DD1BC08823C9F49091B8019230A8F4A4 +:207E80008091E800877F8093E8009093B40145DD8091B401882331F48091E30087FD02C01E +:207EA00081E001C084E08EBB70DC8091E80083FF0AC08091EB0080628093EB008091E8008D +:207EC000877F8093E8000F900F90CF91DF911F910F91089508951F938EB3882361F0109179 +:207EE000E9001092E9008091E80083FF01C0E4DE17701093E9001F910895F999FECF92BD02 +:207F000081BDF89A992780B50895262FF999FECF1FBA92BD81BD20BD0FB6F894FA9AF99A90 +:207F20000FBE01960895F894FFCF4341544552494E4100777700080000000000000801128E +:207F4000011001020000084123360001000201000109023E00020100803209040000010258 +:207F60000201000524001001042402040524060001070582030800FF09040100020A0000B4 +:207F8000000705040210000107058302100001040309042203410072006400750069006E80 +:207FA000006F0020004C0065006F006E006100720064006F00000018034100720064007557 +:127FC0000069006E006F0020004C004C0043000000006E +:00000001FF diff --git a/bootloaders/caterina/Caterina.c b/bootloaders/caterina/Caterina.c new file mode 100755 index 0000000..abcba2b --- /dev/null +++ b/bootloaders/caterina/Caterina.c @@ -0,0 +1,714 @@ +/*
 +             LUFA Library
 +     Copyright (C) Dean Camera, 2011.
 +
 +  dean [at] fourwalledcubicle [dot] com
 +           www.lufa-lib.org
 +*/
 +
 +/*
 +  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 +
 +  Permission to use, copy, modify, distribute, and sell this
 +  software and its documentation for any purpose is hereby granted
 +  without fee, provided that the above copyright notice appear in
 +  all copies and that both that the copyright notice and this
 +  permission notice and warranty disclaimer appear in supporting
 +  documentation, and that the name of the author not be used in
 +  advertising or publicity pertaining to distribution of the
 +  software without specific, written prior permission.
 +
 +  The author disclaim all warranties with regard to this
 +  software, including all implied warranties of merchantability
 +  and fitness.  In no event shall the author be liable for any
 +  special, indirect or consequential damages or any damages
 +  whatsoever resulting from loss of use, data or profits, whether
 +  in an action of contract, negligence or other tortious action,
 +  arising out of or in connection with the use or performance of
 +  this software.
 +*/
 +
 +/** \file
 + *
 + *  Main source file for the CDC class bootloader. This file contains the complete bootloader logic.
 + */
 +
 +#define  INCLUDE_FROM_CATERINA_C
 +#include "Caterina.h"
 +
 +/** Contains the current baud rate and other settings of the first virtual serial port. This must be retained as some
 + *  operating systems will not open the port unless the settings can be set successfully.
 + */
 +static CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 0,
 +                                           .CharFormat  = CDC_LINEENCODING_OneStopBit,
 +                                           .ParityType  = CDC_PARITY_None,
 +                                           .DataBits    = 8                            };
 +
 +/** Current address counter. This stores the current address of the FLASH or EEPROM as set by the host,
 + *  and is used when reading or writing to the AVRs memory (either FLASH or EEPROM depending on the issued
 + *  command.)
 + */
 +static uint32_t CurrAddress;
 +
 +/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
 + *  via a watchdog reset. When cleared the bootloader will exit, starting the watchdog and entering an infinite
 + *  loop until the AVR restarts and the application runs.
 + */
 +static bool RunBootloader = true;
 +
 +/* Pulse generation counters to keep track of the time remaining for each pulse type */
 +#define TX_RX_LED_PULSE_PERIOD 100
 +uint16_t TxLEDPulse = 0; // time remaining for Tx LED pulse
 +uint16_t RxLEDPulse = 0; // time remaining for Rx LED pulse
 +
 +/* Bootloader timeout timer */
 +#define TIMEOUT_PERIOD	8000
 +uint16_t Timeout = 0;
 +
 +uint16_t bootKey = 0x7777;
 +volatile uint16_t *const bootKeyPtr = (volatile uint16_t *)0x0800;
 +
 +void StartSketch(void)
 +{
 +	cli();
 +	
 +	/* Undo TIMER1 setup and clear the count before running the sketch */
 +	TIMSK1 = 0;
 +	TCCR1B = 0;
 +	TCNT1H = 0;		// 16-bit write to TCNT1 requires high byte be written first
 +	TCNT1L = 0;
 +	
 +	/* Relocate the interrupt vector table to the application section */
 +	MCUCR = (1 << IVCE);
 +	MCUCR = 0;
 +
 +	L_LED_OFF();
 +	TX_LED_OFF();
 +	RX_LED_OFF();
 +
 +	/* jump to beginning of application space */
 +	__asm__ volatile("jmp 0x0000");
 +}
 +
 +/*	Breathing animation on L LED indicates bootloader is running */
 +uint16_t LLEDPulse;
 +void LEDPulse(void)
 +{
 +	LLEDPulse++;
 +	uint8_t p = LLEDPulse >> 8;
 +	if (p > 127)
 +		p = 254-p;
 +	p += p;
 +	if (((uint8_t)LLEDPulse) > p)
 +		L_LED_OFF();
 +	else
 +		L_LED_ON();
 +}
 +
 +/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
 + *  runs the bootloader processing routine until it times out or is instructed to exit.
 + */
 +int main(void)
 +{
 +	/* Save the value of the boot key memory before it is overwritten */
 +	uint16_t bootKeyPtrVal = *bootKeyPtr;
 +	*bootKeyPtr = 0;
 +
 +	/* Check the reason for the reset so we can act accordingly */
 +	uint8_t  mcusr_state = MCUSR;		// store the initial state of the Status register
 +	MCUSR = 0;							// clear all reset flags	
 +
 +	/* Watchdog may be configured with a 15 ms period so must disable it before going any further */
 +	wdt_disable();
 +	
 +	if (mcusr_state & (1<<EXTRF)) {
 +		// External reset -  we should continue to self-programming mode.
 +	} else if (mcusr_state == (1<<PORF) && pgm_read_word(0) != 0xFFFF) {		
 +		// After a power-on reset skip the bootloader and jump straight to sketch 
 +		// if one exists.	
 +		StartSketch();
 +	} else if ((mcusr_state == (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) {	
 +		// If it looks like an "accidental" watchdog reset then start the sketch.
 +		StartSketch();
 +	}
 +	
 +	/* Setup hardware required for the bootloader */
 +	SetupHardware();
 +
 +	/* Enable global interrupts so that the USB stack can function */
 +	sei();
 +	
 +	Timeout = 0;
 +	
 +	while (RunBootloader)
 +	{
 +		CDC_Task();
 +		USB_USBTask();
 +		/* Time out and start the sketch if one is present */
 +		if (Timeout > TIMEOUT_PERIOD)
 +			RunBootloader = false;
 +
 +		LEDPulse();
 +	}
 +
 +	/* Disconnect from the host - USB interface will be reset later along with the AVR */
 +	USB_Detach();
 +
 +	/* Jump to beginning of application space to run the sketch - do not reset */	
 +	StartSketch();
 +}
 +
 +/** Configures all hardware required for the bootloader. */
 +void SetupHardware(void)
 +{
 +	/* Disable watchdog if enabled by bootloader/fuses */
 +	MCUSR &= ~(1 << WDRF);
 +	wdt_disable();
 +
 +	/* Disable clock division */
 +	clock_prescale_set(clock_div_1);
 +
 +	/* Relocate the interrupt vector table to the bootloader section */
 +	MCUCR = (1 << IVCE);
 +	MCUCR = (1 << IVSEL);
 +	
 +	LED_SETUP();
 +	CPU_PRESCALE(0); 
 +	L_LED_OFF();
 +	TX_LED_OFF();
 +	RX_LED_OFF();
 +	
 +	/* Initialize TIMER1 to handle bootloader timeout and LED tasks.  
 +	 * With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz
 +	 * Our chosen compare match generates an interrupt every 1 ms.
 +	 * This interrupt is disabled selectively when doing memory reading, erasing,
 +	 * or writing since SPM has tight timing requirements.
 +	 */ 
 +	OCR1AH = 0;
 +	OCR1AL = 250;
 +	TIMSK1 = (1 << OCIE1A);					// enable timer 1 output compare A match interrupt
 +	TCCR1B = ((1 << CS11) | (1 << CS10));	// 1/64 prescaler on timer 1 input
 +
 +	/* Initialize USB Subsystem */
 +	USB_Init();
 +}
 +
 +//uint16_t ctr = 0;
 +ISR(TIMER1_COMPA_vect, ISR_BLOCK)
 +{
 +	/* Reset counter */
 +	TCNT1H = 0;
 +	TCNT1L = 0;
 +
 +	/* Check whether the TX or RX LED one-shot period has elapsed.  if so, turn off the LED */
 +	if (TxLEDPulse && !(--TxLEDPulse))
 +		TX_LED_OFF();
 +	if (RxLEDPulse && !(--RxLEDPulse))
 +		RX_LED_OFF();
 +	
 +	if (pgm_read_word(0) != 0xFFFF)
 +		Timeout++;
 +}
 +
 +/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
 + *  to relay data to and from the attached USB host.
 + */
 +void EVENT_USB_Device_ConfigurationChanged(void)
 +{
 +	/* Setup CDC Notification, Rx and Tx Endpoints */
 +	Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
 +	                           ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
 +	                           ENDPOINT_BANK_SINGLE);
 +
 +	Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
 +	                           ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
 +	                           ENDPOINT_BANK_SINGLE);
 +
 +	Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
 +	                           ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
 +	                           ENDPOINT_BANK_SINGLE);
 +}
 +
 +/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
 + *  the device from the USB host before passing along unhandled control requests to the library for processing
 + *  internally.
 + */
 +void EVENT_USB_Device_ControlRequest(void)
 +{
 +	/* Ignore any requests that aren't directed to the CDC interface */
 +	if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
 +	    (REQTYPE_CLASS | REQREC_INTERFACE))
 +	{
 +		return;
 +	}
 +
 +	/* Process CDC specific control requests */
 +	switch (USB_ControlRequest.bRequest)
 +	{
 +		case CDC_REQ_GetLineEncoding:
 +			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 +			{
 +				Endpoint_ClearSETUP();
 +
 +				/* Write the line coding data to the control endpoint */
 +				Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
 +				Endpoint_ClearOUT();
 +			}
 +
 +			break;
 +		case CDC_REQ_SetLineEncoding:
 +			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 +			{
 +				Endpoint_ClearSETUP();
 +
 +				/* Read the line coding data in from the host into the global struct */
 +				Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
 +				Endpoint_ClearIN();
 +			}
 +
 +			break;
 +	}
 +}
 +
 +#if !defined(NO_BLOCK_SUPPORT)
 +/** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending
 + *  on the AVR910 protocol command issued.
 + *
 + *  \param[in] Command  Single character AVR910 protocol command indicating what memory operation to perform
 + */
 +static void ReadWriteMemoryBlock(const uint8_t Command)
 +{
 +	uint16_t BlockSize;
 +	char     MemoryType;
 +
 +	bool     HighByte = false;
 +	uint8_t  LowByte  = 0;
 +
 +	BlockSize  = (FetchNextCommandByte() << 8);
 +	BlockSize |=  FetchNextCommandByte();
 +
 +	MemoryType =  FetchNextCommandByte();
 +
 +	if ((MemoryType != 'E') && (MemoryType != 'F'))
 +	{
 +		/* Send error byte back to the host */
 +		WriteNextResponseByte('?');
 +
 +		return;
 +	}
 +
 +	/* Disable timer 1 interrupt - can't afford to process nonessential interrupts
 +	 * while doing SPM tasks */
 +	TIMSK1 = 0;
 +
 +	/* Check if command is to read memory */
 +	if (Command == 'g')
 +	{		
 +		/* Re-enable RWW section */
 +		boot_rww_enable();
 +
 +		while (BlockSize--)
 +		{
 +			if (MemoryType == 'F')
 +			{
 +				/* Read the next FLASH byte from the current FLASH page */
 +				#if (FLASHEND > 0xFFFF)
 +				WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte));
 +				#else
 +				WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte));
 +				#endif
 +
 +				/* If both bytes in current word have been read, increment the address counter */
 +				if (HighByte)
 +				  CurrAddress += 2;
 +
 +				HighByte = !HighByte;
 +			}
 +			else
 +			{
 +				/* Read the next EEPROM byte into the endpoint */
 +				WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1)));
 +
 +				/* Increment the address counter after use */
 +				CurrAddress += 2;
 +			}
 +		}
 +	}
 +	else
 +	{
 +		uint32_t PageStartAddress = CurrAddress;
 +
 +		if (MemoryType == 'F')
 +		{
 +			boot_page_erase(PageStartAddress);
 +			boot_spm_busy_wait();
 +		}
 +
 +		while (BlockSize--)
 +		{
 +			if (MemoryType == 'F')
 +			{
 +				/* If both bytes in current word have been written, increment the address counter */
 +				if (HighByte)
 +				{
 +					/* Write the next FLASH word to the current FLASH page */
 +					boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte));
 +
 +					/* Increment the address counter after use */
 +					CurrAddress += 2;
 +				}
 +				else
 +				{
 +					LowByte = FetchNextCommandByte();
 +				}
 +				
 +				HighByte = !HighByte;
 +			}
 +			else
 +			{
 +				/* Write the next EEPROM byte from the endpoint */
 +				eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
 +
 +				/* Increment the address counter after use */
 +				CurrAddress += 2;
 +			}
 +		}
 +
 +		/* If in FLASH programming mode, commit the page after writing */
 +		if (MemoryType == 'F')
 +		{
 +			/* Commit the flash page to memory */
 +			boot_page_write(PageStartAddress);
 +
 +			/* Wait until write operation has completed */
 +			boot_spm_busy_wait();
 +		}
 +
 +		/* Send response byte back to the host */
 +		WriteNextResponseByte('\r');
 +	}
 +
 +	/* Re-enable timer 1 interrupt disabled earlier in this routine */	
 +	TIMSK1 = (1 << OCIE1A);
 +}
 +#endif
 +
 +/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed
 + *  to allow reception of the next data packet from the host.
 + *
 + *  \return Next received byte from the host in the CDC data OUT endpoint
 + */
 +static uint8_t FetchNextCommandByte(void)
 +{
 +	/* Select the OUT endpoint so that the next data byte can be read */
 +	Endpoint_SelectEndpoint(CDC_RX_EPNUM);
 +
 +	/* If OUT endpoint empty, clear it and wait for the next packet from the host */
 +	while (!(Endpoint_IsReadWriteAllowed()))
 +	{
 +		Endpoint_ClearOUT();
 +
 +		while (!(Endpoint_IsOUTReceived()))
 +		{
 +			if (USB_DeviceState == DEVICE_STATE_Unattached)
 +			  return 0;
 +		}
 +	}
 +
 +	/* Fetch the next byte from the OUT endpoint */
 +	return Endpoint_Read_8();
 +}
 +
 +/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the
 + *  bank when full ready for the next byte in the packet to the host.
 + *
 + *  \param[in] Response  Next response byte to send to the host
 + */
 +static void WriteNextResponseByte(const uint8_t Response)
 +{
 +	/* Select the IN endpoint so that the next data byte can be written */
 +	Endpoint_SelectEndpoint(CDC_TX_EPNUM);
 +
 +	/* If IN endpoint full, clear it and wait until ready for the next packet to the host */
 +	if (!(Endpoint_IsReadWriteAllowed()))
 +	{
 +		Endpoint_ClearIN();
 +
 +		while (!(Endpoint_IsINReady()))
 +		{
 +			if (USB_DeviceState == DEVICE_STATE_Unattached)
 +			  return;
 +		}
 +	}
 +
 +	/* Write the next byte to the IN endpoint */
 +	Endpoint_Write_8(Response);
 +	
 +	TX_LED_ON();
 +	TxLEDPulse = TX_RX_LED_PULSE_PERIOD;
 +}
 +
 +#define STK_OK              0x10
 +#define STK_INSYNC          0x14  // ' '
 +#define CRC_EOP             0x20  // 'SPACE'
 +#define STK_GET_SYNC        0x30  // '0'
 +
 +#define STK_GET_PARAMETER   0x41  // 'A'
 +#define STK_SET_DEVICE      0x42  // 'B'
 +#define STK_SET_DEVICE_EXT  0x45  // 'E'
 +#define STK_LOAD_ADDRESS    0x55  // 'U'
 +#define STK_UNIVERSAL       0x56  // 'V'
 +#define STK_PROG_PAGE       0x64  // 'd'
 +#define STK_READ_PAGE       0x74  // 't'
 +#define STK_READ_SIGN       0x75  // 'u'
 +
 +/** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions
 + *  and send the appropriate response back to the host.
 + */
 +void CDC_Task(void)
 +{
 +	/* Select the OUT endpoint */
 +	Endpoint_SelectEndpoint(CDC_RX_EPNUM);
 +
 +	/* Check if endpoint has a command in it sent from the host */
 +	if (!(Endpoint_IsOUTReceived()))
 +	  return;
 +	  
 +	RX_LED_ON();
 +	RxLEDPulse = TX_RX_LED_PULSE_PERIOD;
 +
 +	/* Read in the bootloader command (first byte sent from host) */
 +	uint8_t Command = FetchNextCommandByte();
 +
 +	if (Command == 'E')
 +	{
 +		/* We nearly run out the bootloader timeout clock, 
 +		* leaving just a few hundred milliseconds so the 
 +		* bootloder has time to respond and service any 
 +		* subsequent requests */
 +		Timeout = TIMEOUT_PERIOD - 500;
 +	
 +		/* Re-enable RWW section - must be done here in case 
 +		 * user has disabled verification on upload.  */
 +		boot_rww_enable_safe();		
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 'T')
 +	{
 +		FetchNextCommandByte();
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if ((Command == 'L') || (Command == 'P'))
 +	{
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 't')
 +	{
 +		// Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader 
 +		WriteNextResponseByte(0x44);
 +		WriteNextResponseByte(0x00);
 +	}
 +	else if (Command == 'a')
 +	{
 +		// Indicate auto-address increment is supported 
 +		WriteNextResponseByte('Y');
 +	}
 +	else if (Command == 'A')
 +	{
 +		// Set the current address to that given by the host 
 +		CurrAddress   = (FetchNextCommandByte() << 9);
 +		CurrAddress  |= (FetchNextCommandByte() << 1);
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 'p')
 +	{
 +		// Indicate serial programmer back to the host 
 +		WriteNextResponseByte('S');
 +	}
 +	else if (Command == 'S')
 +	{
 +		// Write the 7-byte software identifier to the endpoint 
 +		for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++)
 +		  WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]);
 +	}
 +	else if (Command == 'V')
 +	{
 +		WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR);
 +		WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR);
 +	}
 +	else if (Command == 's')
 +	{
 +		WriteNextResponseByte(AVR_SIGNATURE_3);
 +		WriteNextResponseByte(AVR_SIGNATURE_2);
 +		WriteNextResponseByte(AVR_SIGNATURE_1);
 +	}
 +	else if (Command == 'e')
 +	{
 +		// Clear the application section of flash 
 +		for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
 +		{
 +			boot_page_erase(CurrFlashAddress);
 +			boot_spm_busy_wait();
 +			boot_page_write(CurrFlashAddress);
 +			boot_spm_busy_wait();
 +		}
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	#if !defined(NO_LOCK_BYTE_WRITE_SUPPORT)
 +	else if (Command == 'l')
 +	{
 +		// Set the lock bits to those given by the host 
 +		boot_lock_bits_set(FetchNextCommandByte());
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	#endif
 +	else if (Command == 'r')
 +	{
 +		WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS));
 +	}
 +	else if (Command == 'F')
 +	{
 +		WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS));
 +	}
 +	else if (Command == 'N')
 +	{
 +		WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS));
 +	}
 +	else if (Command == 'Q')
 +	{
 +		WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS));
 +	}
 +	#if !defined(NO_BLOCK_SUPPORT)
 +	else if (Command == 'b')
 +	{
 +		WriteNextResponseByte('Y');
 +
 +		// Send block size to the host 
 +		WriteNextResponseByte(SPM_PAGESIZE >> 8);
 +		WriteNextResponseByte(SPM_PAGESIZE & 0xFF);
 +	}
 +	else if ((Command == 'B') || (Command == 'g'))
 +	{
 +		// Keep resetting the timeout counter if we're receiving self-programming instructions
 +		Timeout = 0;
 +		// Delegate the block write/read to a separate function for clarity 
 +		ReadWriteMemoryBlock(Command);
 +	}
 +	#endif
 +	#if !defined(NO_FLASH_BYTE_SUPPORT)
 +	else if (Command == 'C')
 +	{
 +		// Write the high byte to the current flash page
 +		boot_page_fill(CurrAddress, FetchNextCommandByte());
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 'c')
 +	{
 +		// Write the low byte to the current flash page 
 +		boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte());
 +
 +		// Increment the address 
 +		CurrAddress += 2;
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 'm')
 +	{
 +		// Commit the flash page to memory
 +		boot_page_write(CurrAddress);
 +
 +		// Wait until write operation has completed 
 +		boot_spm_busy_wait();
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 'R')
 +	{
 +		#if (FLASHEND > 0xFFFF)
 +		uint16_t ProgramWord = pgm_read_word_far(CurrAddress);
 +		#else
 +		uint16_t ProgramWord = pgm_read_word(CurrAddress);
 +		#endif
 +
 +		WriteNextResponseByte(ProgramWord >> 8);
 +		WriteNextResponseByte(ProgramWord & 0xFF);
 +	}
 +	#endif
 +	#if !defined(NO_EEPROM_BYTE_SUPPORT)
 +	else if (Command == 'D')
 +	{
 +		// Read the byte from the endpoint and write it to the EEPROM 
 +		eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
 +
 +		// Increment the address after use
 +		CurrAddress += 2;
 +
 +		// Send confirmation byte back to the host 
 +		WriteNextResponseByte('\r');
 +	}
 +	else if (Command == 'd')
 +	{
 +		// Read the EEPROM byte and write it to the endpoint 
 +		WriteNextResponseByte(eeprom_read_byte((uint8_t*)((intptr_t)(CurrAddress >> 1))));
 +
 +		// Increment the address after use 
 +		CurrAddress += 2;
 +	}
 +	#endif
 +	else if (Command != 27)
 +	{
 +		// Unknown (non-sync) command, return fail code 
 +		WriteNextResponseByte('?');
 +	}
 +	
 +
 +	/* Select the IN endpoint */
 +	Endpoint_SelectEndpoint(CDC_TX_EPNUM);
 +
 +	/* Remember if the endpoint is completely full before clearing it */
 +	bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
 +
 +	/* Send the endpoint data to the host */
 +	Endpoint_ClearIN();
 +
 +	/* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
 +	if (IsEndpointFull)
 +	{
 +		while (!(Endpoint_IsINReady()))
 +		{
 +			if (USB_DeviceState == DEVICE_STATE_Unattached)
 +			  return;
 +		}
 +
 +		Endpoint_ClearIN();
 +	}
 +
 +	/* Wait until the data has been sent to the host */
 +	while (!(Endpoint_IsINReady()))
 +	{
 +		if (USB_DeviceState == DEVICE_STATE_Unattached)
 +		  return;
 +	}
 +
 +	/* Select the OUT endpoint */
 +	Endpoint_SelectEndpoint(CDC_RX_EPNUM);
 +
 +	/* Acknowledge the command from the host */
 +	Endpoint_ClearOUT();
 +}
 +
 diff --git a/bootloaders/caterina/Caterina.h b/bootloaders/caterina/Caterina.h new file mode 100755 index 0000000..f8251d4 --- /dev/null +++ b/bootloaders/caterina/Caterina.h @@ -0,0 +1,99 @@ +/*
 +             LUFA Library
 +     Copyright (C) Dean Camera, 2011.
 +
 +  dean [at] fourwalledcubicle [dot] com
 +           www.lufa-lib.org
 +*/
 +
 +/*
 +  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 +
 +  Permission to use, copy, modify, distribute, and sell this
 +  software and its documentation for any purpose is hereby granted
 +  without fee, provided that the above copyright notice appear in
 +  all copies and that both that the copyright notice and this
 +  permission notice and warranty disclaimer appear in supporting
 +  documentation, and that the name of the author not be used in
 +  advertising or publicity pertaining to distribution of the
 +  software without specific, written prior permission.
 +
 +  The author disclaim all warranties with regard to this
 +  software, including all implied warranties of merchantability
 +  and fitness.  In no event shall the author be liable for any
 +  special, indirect or consequential damages or any damages
 +  whatsoever resulting from loss of use, data or profits, whether
 +  in an action of contract, negligence or other tortious action,
 +  arising out of or in connection with the use or performance of
 +  this software.
 +*/
 +
 +/** \file
 + *
 + *  Header file for BootloaderCDC.c.
 + */
 +
 +#ifndef _CDC_H_
 +#define _CDC_H_
 +
 +	/* Includes: */
 +		#include <avr/io.h>
 +		#include <avr/wdt.h>
 +		#include <avr/boot.h>
 +		#include <avr/eeprom.h>
 +		#include <avr/power.h>
 +		#include <avr/interrupt.h>
 +		#include <stdbool.h>
 +
 +		#include "Descriptors.h"
 +
 +		#include <LUFA/Drivers/USB/USB.h>
 +	/* Macros: */
 +		/** Version major of the CDC bootloader. */
 +		#define BOOTLOADER_VERSION_MAJOR     0x01
 +
 +		/** Version minor of the CDC bootloader. */
 +		#define BOOTLOADER_VERSION_MINOR     0x00
 +
 +		/** Hardware version major of the CDC bootloader. */
 +		#define BOOTLOADER_HWVERSION_MAJOR   0x01
 +
 +		/** Hardware version minor of the CDC bootloader. */
 +		#define BOOTLOADER_HWVERSION_MINOR   0x00
 +
 +		/** Eight character bootloader firmware identifier reported to the host when requested */
 +		#define SOFTWARE_IDENTIFIER          "CATERINA"
 +		
 +		#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n))
 +		#define LED_SETUP()		DDRC |= (1<<7); DDRB |= (1<<0); DDRD |= (1<<5);
 +		#define L_LED_OFF()		PORTC &= ~(1<<7)
 +		#define L_LED_ON()		PORTC |= (1<<7)
 +		#define L_LED_TOGGLE()	PORTC ^= (1<<7)
 +		#define TX_LED_OFF()	PORTD |= (1<<5)
 +		#define TX_LED_ON()		PORTD &= ~(1<<5)
 +		#define RX_LED_OFF()	PORTB |= (1<<0)
 +		#define RX_LED_ON()		PORTB &= ~(1<<0)
 +
 +	/* Type Defines: */
 +		/** Type define for a non-returning pointer to the start of the loaded application in flash memory. */
 +		typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
 +
 +	/* Function Prototypes: */
 +		void StartSketch(void);
 +		void LEDPulse(void);
 +	
 +		void CDC_Task(void);
 +		void SetupHardware(void);
 +
 +		void EVENT_USB_Device_ConfigurationChanged(void);
 +
 +		#if defined(INCLUDE_FROM_CATERINA_C) || defined(__DOXYGEN__)
 +			#if !defined(NO_BLOCK_SUPPORT)
 +			static void    ReadWriteMemoryBlock(const uint8_t Command);
 +			#endif
 +			static uint8_t FetchNextCommandByte(void);
 +			static void    WriteNextResponseByte(const uint8_t Response);
 +		#endif
 +
 +#endif
 +
 diff --git a/bootloaders/caterina/Descriptors.c b/bootloaders/caterina/Descriptors.c new file mode 100755 index 0000000..c5feaf5 --- /dev/null +++ b/bootloaders/caterina/Descriptors.c @@ -0,0 +1,262 @@ +/*
 +             LUFA Library
 +     Copyright (C) Dean Camera, 2011.
 +
 +  dean [at] fourwalledcubicle [dot] com
 +           www.lufa-lib.org
 +*/
 +
 +/*
 +  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 +
 +  Permission to use, copy, modify, distribute, and sell this
 +  software and its documentation for any purpose is hereby granted
 +  without fee, provided that the above copyright notice appear in
 +  all copies and that both that the copyright notice and this
 +  permission notice and warranty disclaimer appear in supporting
 +  documentation, and that the name of the author not be used in
 +  advertising or publicity pertaining to distribution of the
 +  software without specific, written prior permission.
 +
 +  The author disclaim all warranties with regard to this
 +  software, including all implied warranties of merchantability
 +  and fitness.  In no event shall the author be liable for any
 +  special, indirect or consequential damages or any damages
 +  whatsoever resulting from loss of use, data or profits, whether
 +  in an action of contract, negligence or other tortious action,
 +  arising out of or in connection with the use or performance of
 +  this software.
 +*/
 +
 +/** \file
 + *
 + *  USB Device Descriptors, for library use when in USB device mode. Descriptors are special
 + *  computer-readable structures which the host requests upon device enumeration, to determine
 + *  the device's capabilities and functions.
 + */
 +
 +#include "Descriptors.h"
 +
 +/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
 + *  device characteristics, including the supported USB version, control endpoint size and the
 + *  number of device configurations. The descriptor is read out by the USB host when the enumeration
 + *  process begins.
 + */
 +const USB_Descriptor_Device_t DeviceDescriptor =
 +{
 +	.Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
 +
 +	.USBSpecification       = VERSION_BCD(01.10),
 +	.Class                  = CDC_CSCP_CDCClass,
 +	.SubClass               = CDC_CSCP_NoSpecificSubclass,
 +	.Protocol               = CDC_CSCP_NoSpecificProtocol,
 +
 +	.Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 +
 +	.VendorID               = DEVICE_VID,
 +	.ProductID              = DEVICE_PID,
 +	.ReleaseNumber          = VERSION_BCD(00.01),
 +
 +	.ManufacturerStrIndex   = 0x02,
 +	.ProductStrIndex        = 0x01,
 +	.SerialNumStrIndex      = NO_DESCRIPTOR,
 +
 +	.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
 +};
 +
 +/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
 + *  of the device in one of its supported configurations, including information about any device interfaces
 + *  and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
 + *  a configuration so that the host may correctly communicate with the USB device.
 + */
 +const USB_Descriptor_Configuration_t ConfigurationDescriptor =
 +{
 +	.Config =
 +		{
 +			.Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
 +
 +			.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
 +			.TotalInterfaces        = 2,
 +
 +			.ConfigurationNumber    = 1,
 +			.ConfigurationStrIndex  = NO_DESCRIPTOR,
 +
 +			.ConfigAttributes       = USB_CONFIG_ATTR_BUSPOWERED,
 +
 +			.MaxPowerConsumption    = USB_CONFIG_POWER_MA(100)
 +		},
 +
 +	.CDC_CCI_Interface =
 +		{
 +			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
 +
 +			.InterfaceNumber        = 0,
 +			.AlternateSetting       = 0,
 +
 +			.TotalEndpoints         = 1,
 +
 +			.Class                  = CDC_CSCP_CDCClass,
 +			.SubClass               = CDC_CSCP_ACMSubclass,
 +			.Protocol               = CDC_CSCP_ATCommandProtocol,
 +
 +			.InterfaceStrIndex      = NO_DESCRIPTOR
 +		},
 +
 +	.CDC_Functional_Header =
 +		{
 +			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
 +			.Subtype                = 0x00,
 +
 +			.CDCSpecification       = VERSION_BCD(01.10),
 +		},
 +
 +	.CDC_Functional_ACM =
 +		{
 +			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
 +			.Subtype                = 0x02,
 +
 +			.Capabilities           = 0x04,
 +		},
 +
 +	.CDC_Functional_Union =
 +		{
 +			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
 +			.Subtype                = 0x06,
 +
 +			.MasterInterfaceNumber  = 0,
 +			.SlaveInterfaceNumber   = 1,
 +		},
 +
 +	.CDC_NotificationEndpoint =
 +		{
 +			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 +
 +			.EndpointAddress        = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
 +			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 +			.EndpointSize           = CDC_NOTIFICATION_EPSIZE,
 +			.PollingIntervalMS      = 0xFF
 +		},
 +
 +	.CDC_DCI_Interface =
 +		{
 +			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
 +
 +			.InterfaceNumber        = 1,
 +			.AlternateSetting       = 0,
 +
 +			.TotalEndpoints         = 2,
 +
 +			.Class                  = CDC_CSCP_CDCDataClass,
 +			.SubClass               = CDC_CSCP_NoDataSubclass,
 +			.Protocol               = CDC_CSCP_NoDataProtocol,
 +
 +			.InterfaceStrIndex      = NO_DESCRIPTOR
 +		},
 +
 +	.CDC_DataOutEndpoint =
 +		{
 +			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 +
 +			.EndpointAddress        = (ENDPOINT_DIR_OUT | CDC_RX_EPNUM),
 +			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 +			.EndpointSize           = CDC_TXRX_EPSIZE,
 +			.PollingIntervalMS      = 0x01
 +		},
 +
 +	.CDC_DataInEndpoint =
 +		{
 +			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 +
 +			.EndpointAddress        = (ENDPOINT_DIR_IN | CDC_TX_EPNUM),
 +			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 +			.EndpointSize           = CDC_TXRX_EPSIZE,
 +			.PollingIntervalMS      = 0x01
 +		}
 +};
 +
 +/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
 + *  the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
 + *  via the language ID table available at USB.org what languages the device supports for its string descriptors.
 + */
 +const USB_Descriptor_String_t LanguageString =
 +{
 +	.Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
 +
 +	.UnicodeString          = {LANGUAGE_ID_ENG}
 +};
 +
 +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
 + *  and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
 + *  Descriptor.
 + */
 +const USB_Descriptor_String_t ProductString =
 +{
 +	.Header                 = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},
 +
 +	#if DEVICE_PID == 0x0036
 +	.UnicodeString          = L"Arduino Leonardo" 
 +	#else
 +	.UnicodeString			= L"USB IO board    "
 +	#endif
 +};
 +
 +const USB_Descriptor_String_t ManufNameString = 
 +{
 +	.Header					= {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
 +	
 +	#if DEVICE_VID == 0x2341
 +	.UnicodeString			= L"Arduino LLC"
 +	#else
 +	.UnicodeString			= L"Unknown    "
 +	#endif
 +};
 +
 +/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors"
 + *  documentation) by the application code so that the address and size of a requested descriptor can be given
 + *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
 + *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
 + *  USB host.
 + */
 +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
 +                                    const uint8_t wIndex,
 +                                    const void** const DescriptorAddress)
 +{
 +	const uint8_t  DescriptorType   = (wValue >> 8);
 +	const uint8_t  DescriptorNumber = (wValue & 0xFF);
 +
 +	const void* Address = NULL;
 +	uint16_t    Size    = NO_DESCRIPTOR;
 +
 +	switch (DescriptorType)
 +	{
 +		case DTYPE_Device:
 +			Address = &DeviceDescriptor;
 +			Size    = sizeof(USB_Descriptor_Device_t);
 +			break;
 +		case DTYPE_Configuration:
 +			Address = &ConfigurationDescriptor;
 +			Size    = sizeof(USB_Descriptor_Configuration_t);
 +			break;
 +		case DTYPE_String:
 +			if (!(DescriptorNumber))
 +			{
 +				Address = &LanguageString;
 +				Size    = LanguageString.Header.Size;
 +			}
 +			else if (DescriptorNumber == DeviceDescriptor.ProductStrIndex) 
 +			{
 +				Address = &ProductString;
 +				Size    = ProductString.Header.Size;
 +			} else if (DescriptorNumber == DeviceDescriptor.ManufacturerStrIndex)
 +			{
 +				Address = &ManufNameString;
 +				Size	= ManufNameString.Header.Size;
 +			}
 +
 +			break;
 +	}
 +
 +	*DescriptorAddress = Address;
 +	return Size;
 +}
 +
 diff --git a/bootloaders/caterina/Descriptors.h b/bootloaders/caterina/Descriptors.h new file mode 100755 index 0000000..94091ae --- /dev/null +++ b/bootloaders/caterina/Descriptors.h @@ -0,0 +1,139 @@ +/*
 +             LUFA Library
 +     Copyright (C) Dean Camera, 2011.
 +
 +  dean [at] fourwalledcubicle [dot] com
 +           www.lufa-lib.org
 +*/
 +
 +/*
 +  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 +
 +  Permission to use, copy, modify, distribute, and sell this
 +  software and its documentation for any purpose is hereby granted
 +  without fee, provided that the above copyright notice appear in
 +  all copies and that both that the copyright notice and this
 +  permission notice and warranty disclaimer appear in supporting
 +  documentation, and that the name of the author not be used in
 +  advertising or publicity pertaining to distribution of the
 +  software without specific, written prior permission.
 +
 +  The author disclaim all warranties with regard to this
 +  software, including all implied warranties of merchantability
 +  and fitness.  In no event shall the author be liable for any
 +  special, indirect or consequential damages or any damages
 +  whatsoever resulting from loss of use, data or profits, whether
 +  in an action of contract, negligence or other tortious action,
 +  arising out of or in connection with the use or performance of
 +  this software.
 +*/
 +
 +/** \file
 + *
 + *  Header file for Descriptors.c.
 + */
 +
 +#ifndef _DESCRIPTORS_H_
 +#define _DESCRIPTORS_H_
 +
 +	/* Includes: */
 +		#include <LUFA/Drivers/USB/USB.h>
 +
 +	/* Macros: */
 +		#if defined(__AVR_AT90USB1287__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x97
 +			#define AVR_SIGNATURE_3               0x82
 +		#elif defined(__AVR_AT90USB647__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x96
 +			#define AVR_SIGNATURE_3               0x82
 +		#elif defined(__AVR_AT90USB1286__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x97
 +			#define AVR_SIGNATURE_3               0x82
 +		#elif defined(__AVR_AT90USB646__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x96
 +			#define AVR_SIGNATURE_3               0x82
 +		#elif defined(__AVR_ATmega32U6__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x95
 +			#define AVR_SIGNATURE_3               0x88
 +		#elif defined(__AVR_ATmega32U4__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x95
 +			#define AVR_SIGNATURE_3               0x87
 +		#elif defined(__AVR_ATmega16U4__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x94
 +			#define AVR_SIGNATURE_3               0x88
 +		#elif defined(__AVR_ATmega32U2__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x95
 +			#define AVR_SIGNATURE_3               0x8A
 +		#elif defined(__AVR_ATmega16U2__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x94
 +			#define AVR_SIGNATURE_3               0x89
 +		#elif defined(__AVR_AT90USB162__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x94
 +			#define AVR_SIGNATURE_3               0x82
 +		#elif defined(__AVR_ATmega8U2__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x93
 +			#define AVR_SIGNATURE_3               0x89
 +		#elif defined(__AVR_AT90USB82__)
 +			#define AVR_SIGNATURE_1               0x1E
 +			#define AVR_SIGNATURE_2               0x94
 +			#define AVR_SIGNATURE_3               0x82
 +		#else
 +			#error The selected AVR part is not currently supported by this bootloader.
 +		#endif
 +
 +		/** Endpoint number for the CDC control interface event notification endpoint. */
 +		#define CDC_NOTIFICATION_EPNUM         2
 +
 +		/** Endpoint number for the CDC data interface TX (data IN) endpoint. */
 +		#define CDC_TX_EPNUM                   3
 +
 +		/** Endpoint number for the CDC data interface RX (data OUT) endpoint. */
 +		#define CDC_RX_EPNUM                   4
 +
 +		/** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */
 +		#define CDC_TXRX_EPSIZE                16
 +
 +		/** Size of the CDC control interface notification endpoint bank, in bytes. */
 +		#define CDC_NOTIFICATION_EPSIZE        8
 +
 +	/* Type Defines: */
 +		/** Type define for the device configuration descriptor structure. This must be defined in the
 +		 *  application code, as the configuration descriptor contains several sub-descriptors which
 +		 *  vary between devices, and which describe the device's usage to the host.
 +		 */
 +		typedef struct
 +		{
 +			USB_Descriptor_Configuration_Header_t    Config;
 +			
 +			// CDC Control Interface
 +			USB_Descriptor_Interface_t               CDC_CCI_Interface;
 +			USB_CDC_Descriptor_FunctionalHeader_t    CDC_Functional_Header;
 +			USB_CDC_Descriptor_FunctionalACM_t       CDC_Functional_ACM;
 +			USB_CDC_Descriptor_FunctionalUnion_t     CDC_Functional_Union;
 +			USB_Descriptor_Endpoint_t                CDC_NotificationEndpoint;
 +			
 +			// CDC Data Interface
 +			USB_Descriptor_Interface_t               CDC_DCI_Interface;
 +			USB_Descriptor_Endpoint_t                CDC_DataOutEndpoint;
 +			USB_Descriptor_Endpoint_t                CDC_DataInEndpoint;
 +		} USB_Descriptor_Configuration_t;
 +
 +	/* Function Prototypes: */
 +		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
 +		                                    const uint8_t wIndex,
 +		                                    const void** const DescriptorAddress)
 +		                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
 +
 +#endif
 +
 diff --git a/bootloaders/caterina/Makefile b/bootloaders/caterina/Makefile new file mode 100755 index 0000000..873f8bd --- /dev/null +++ b/bootloaders/caterina/Makefile @@ -0,0 +1,728 @@ +# Hey Emacs, this is a -*- makefile -*-
 +#----------------------------------------------------------------------------
 +# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
 +#  >> Modified for use with the LUFA project. <<
 +#
 +# Released to the Public Domain
 +#
 +# Additional material for this makefile was written by:
 +# Peter Fleury
 +# Tim Henigan
 +# Colin O'Flynn
 +# Reiner Patommel
 +# Markus Pfaff
 +# Sander Pool
 +# Frederik Rouleau
 +# Carlos Lamas
 +# Dean Camera
 +# Opendous Inc.
 +# Denver Gingerich
 +#
 +#----------------------------------------------------------------------------
 +# On command line:
 +#
 +# make all = Make software.
 +#
 +# make clean = Clean out built project files.
 +#
 +# make coff = Convert ELF to AVR COFF.
 +#
 +# make extcoff = Convert ELF to AVR Extended COFF.
 +#
 +# make program = Download the hex file to the device, using avrdude.
 +#                Please customize the avrdude settings below first!
 +#
 +# make doxygen = Generate DoxyGen documentation for the project (must have
 +#                DoxyGen installed)
 +#
 +# make debug = Start either simulavr or avarice as specified for debugging,
 +#              with avr-gdb or avr-insight as the front end for debugging.
 +#
 +# make filename.s = Just compile filename.c into the assembler code only.
 +#
 +# make filename.i = Create a preprocessed source file for use in submitting
 +#                   bug reports to the GCC project.
 +#
 +# To rebuild project do "make clean" then "make all".
 +#----------------------------------------------------------------------------
 +
 +# USB vendor ID (VID)
 +# official Arduino LLC VID
 +# VID = 0x2341
 +
 +
 +# USB product ID (PID)
 +# official Leonardo PID
 +# PID = 0x0036
 +
 +
 +# MCU name
 +MCU = atmega32u4
 +
 +
 +# Target architecture (see library "Board Types" documentation).
 +ARCH = AVR8
 +
 +
 +# Target board (see library "Board Types" documentation, NONE for projects not requiring
 +# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
 +# "Board" inside the application directory.
 +BOARD = USER
 +
 +
 +# Processor frequency.
 +#     This will define a symbol, F_CPU, in all source code files equal to the
 +#     processor frequency in Hz. You can then use this symbol in your source code to
 +#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
 +#     automatically to create a 32-bit value in your source code.
 +#
 +#     This will be an integer division of F_USB below, as it is sourced by
 +#     F_USB after it has run through any CPU prescalers. Note that this value
 +#     does not *change* the processor frequency - it should merely be updated to
 +#     reflect the processor speed set externally so that the code can use accurate
 +#     software delays.
 +F_CPU = 16000000
 +
 +
 +# Input clock frequency.
 +#     This will define a symbol, F_USB, in all source code files equal to the
 +#     input clock frequency (before any prescaling is performed) in Hz. This value may
 +#     differ from F_CPU if prescaling is used on the latter, and is required as the
 +#     raw input clock is fed directly to the PLL sections of the AVR for high speed
 +#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
 +#     at the end, this will be done automatically to create a 32-bit value in your
 +#     source code.
 +#
 +#     If no clock division is performed on the input clock inside the AVR (via the
 +#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
 +F_USB = $(F_CPU)
 +
 +
 +# Starting byte address of the bootloader, as a byte address - computed via the formula
 +#   BOOT_START = ((FLASH_SIZE_KB - BOOT_SECTION_SIZE_KB) * 1024)
 +#
 +# Note that the bootloader size and start address given in AVRStudio is in words and not
 +# bytes, and so will need to be doubled to obtain the byte address needed by AVR-GCC.
 +FLASH_SIZE_KB        = 32
 +BOOT_SECTION_SIZE_KB = 4
 +BOOT_START           = 0x$(shell echo "obase=16; ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024" | bc)
 +
 +
 +# Output format. (can be srec, ihex, binary)
 +FORMAT = ihex
 +
 +
 +# Target file name (without extension).
 +TARGET = Caterina
 +
 +
 +# Object files directory
 +#     To put object files in current directory, use a dot (.), do NOT make
 +#     this an empty or blank macro!
 +OBJDIR = .
 +
 +
 +# Path to the LUFA library
 +LUFA_PATH = ../../../../../LUFA-111009
 +
 +
 +# LUFA library compile-time options and predefined tokens
 +LUFA_OPTS  = -D USB_DEVICE_ONLY
 +LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
 +LUFA_OPTS += -D ORDERED_EP_CONFIG
 +LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
 +LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
 +LUFA_OPTS += -D USE_RAM_DESCRIPTORS
 +LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 +LUFA_OPTS += -D NO_INTERNAL_SERIAL
 +LUFA_OPTS += -D NO_DEVICE_SELF_POWER
 +LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
 +LUFA_OPTS += -D NO_SOF_EVENTS
 +
 +#LUFA_OPTS += -D NO_BLOCK_SUPPORT
 +#LUFA_OPTS += -D NO_EEPROM_BYTE_SUPPORT
 +#LUFA_OPTS += -D NO_FLASH_BYTE_SUPPORT
 +LUFA_OPTS += -D NO_LOCK_BYTE_WRITE_SUPPORT
 +
 +
 +# Create the LUFA source path variables by including the LUFA root makefile
 +include $(LUFA_PATH)/LUFA/makefile
 +
 +
 +# List C source files here. (C dependencies are automatically generated.)
 +SRC = $(TARGET).c                                                 \
 +	  Descriptors.c                                               \
 +	  $(LUFA_SRC_USB)                                             \
 +
 +
 +# List C++ source files here. (C dependencies are automatically generated.)
 +CPPSRC =
 +
 +
 +# List Assembler source files here.
 +#     Make them always end in a capital .S.  Files ending in a lowercase .s
 +#     will not be considered source files but generated files (assembler
 +#     output from the compiler), and will be deleted upon "make clean"!
 +#     Even though the DOS/Win* filesystem matches both .s and .S the same,
 +#     it will preserve the spelling of the filenames, and gcc itself does
 +#     care about how the name is spelled on its command-line.
 +ASRC =
 +
 +
 +# Optimization level, can be [0, 1, 2, 3, s].
 +#     0 = turn off optimization. s = optimize for size.
 +#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
 +OPT = s
 +
 +
 +# Debugging format.
 +#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
 +#     AVR Studio 4.10 requires dwarf-2.
 +#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
 +DEBUG = dwarf-2
 +
 +
 +# List any extra directories to look for include files here.
 +#     Each directory must be seperated by a space.
 +#     Use forward slashes for directory separators.
 +#     For a directory that has spaces, enclose it in quotes.
 +EXTRAINCDIRS = $(LUFA_PATH)/
 +
 +
 +# Compiler flag to set the C Standard level.
 +#     c89   = "ANSI" C
 +#     gnu89 = c89 plus GCC extensions
 +#     c99   = ISO C99 standard (not yet fully implemented)
 +#     gnu99 = c99 plus GCC extensions
 +CSTANDARD = -std=c99
 +
 +
 +# Place -D or -U options here for C sources
 +CDEFS  = -DF_CPU=$(F_CPU)UL
 +CDEFS += -DF_USB=$(F_USB)UL
 +CDEFS += -DBOARD=BOARD_$(BOARD) -DARCH=ARCH_$(ARCH)
 +CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
 +CDEFS += -DDEVICE_VID=$(VID)UL
 +CDEFS += -DDEVICE_PID=$(PID)UL
 +CDEFS += $(LUFA_OPTS)
 +
 +
 +# Place -D or -U options here for ASM sources
 +ADEFS  = -DF_CPU=$(F_CPU)
 +ADEFS += -DF_USB=$(F_USB)UL
 +ADEFS += -DBOARD=BOARD_$(BOARD)
 +ADEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
 +ADEFS += $(LUFA_OPTS)
 +
 +
 +# Place -D or -U options here for C++ sources
 +CPPDEFS  = -DF_CPU=$(F_CPU)UL
 +CPPDEFS += -DF_USB=$(F_USB)UL
 +CPPDEFS += -DBOARD=BOARD_$(BOARD)
 +CPPDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
 +CPPDEFS += $(LUFA_OPTS)
 +#CPPDEFS += -D__STDC_LIMIT_MACROS
 +#CPPDEFS += -D__STDC_CONSTANT_MACROS
 +
 +
 +
 +#---------------- Compiler Options C ----------------
 +#  -g*:          generate debugging information
 +#  -O*:          optimization level
 +#  -f...:        tuning, see GCC manual and avr-libc documentation
 +#  -Wall...:     warning level
 +#  -Wa,...:      tell GCC to pass this to the assembler.
 +#    -adhlns...: create assembler listing
 +CFLAGS = -g$(DEBUG)
 +CFLAGS += $(CDEFS)
 +CFLAGS += -O$(OPT)
 +CFLAGS += -funsigned-char
 +CFLAGS += -funsigned-bitfields
 +CFLAGS += -ffunction-sections
 +CFLAGS += -fno-inline-small-functions
 +CFLAGS += -fpack-struct
 +CFLAGS += -fshort-enums
 +CFLAGS += -fno-strict-aliasing
 +CFLAGS += -Wall
 +CFLAGS += -Wstrict-prototypes
 +#CFLAGS += -mshort-calls
 +#CFLAGS += -fno-unit-at-a-time
 +#CFLAGS += -Wundef
 +#CFLAGS += -Wunreachable-code
 +#CFLAGS += -Wsign-compare
 +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
 +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
 +CFLAGS += $(CSTANDARD)
 +
 +
 +#---------------- Compiler Options C++ ----------------
 +#  -g*:          generate debugging information
 +#  -O*:          optimization level
 +#  -f...:        tuning, see GCC manual and avr-libc documentation
 +#  -Wall...:     warning level
 +#  -Wa,...:      tell GCC to pass this to the assembler.
 +#    -adhlns...: create assembler listing
 +CPPFLAGS = -g$(DEBUG)
 +CPPFLAGS += $(CPPDEFS)
 +CPPFLAGS += -O$(OPT)
 +CPPFLAGS += -funsigned-char
 +CPPFLAGS += -funsigned-bitfields
 +CPPFLAGS += -fpack-struct
 +CPPFLAGS += -fshort-enums
 +CPPFLAGS += -fno-exceptions
 +CPPFLAGS += -Wall
 +CPPFLAGS += -Wundef
 +#CPPFLAGS += -mshort-calls
 +#CPPFLAGS += -fno-unit-at-a-time
 +#CPPFLAGS += -Wstrict-prototypes
 +#CPPFLAGS += -Wunreachable-code
 +#CPPFLAGS += -Wsign-compare
 +CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
 +CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
 +#CPPFLAGS += $(CSTANDARD)
 +
 +
 +#---------------- Assembler Options ----------------
 +#  -Wa,...:   tell GCC to pass this to the assembler.
 +#  -adhlns:   create listing
 +#  -gstabs:   have the assembler create line number information; note that
 +#             for use in COFF files, additional information about filenames
 +#             and function names needs to be present in the assembler source
 +#             files -- see avr-libc docs [FIXME: not yet described there]
 +#  -listing-cont-lines: Sets the maximum number of continuation lines of hex
 +#       dump that will be displayed for a given single line of source input.
 +ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
 +
 +
 +#---------------- Library Options ----------------
 +# Minimalistic printf version
 +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
 +
 +# Floating point printf version (requires MATH_LIB = -lm below)
 +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
 +
 +# If this is left blank, then it will use the Standard printf version.
 +PRINTF_LIB =
 +#PRINTF_LIB = $(PRINTF_LIB_MIN)
 +#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
 +
 +
 +# Minimalistic scanf version
 +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
 +
 +# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
 +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
 +
 +# If this is left blank, then it will use the Standard scanf version.
 +SCANF_LIB =
 +#SCANF_LIB = $(SCANF_LIB_MIN)
 +#SCANF_LIB = $(SCANF_LIB_FLOAT)
 +
 +
 +MATH_LIB = -lm
 +
 +
 +# List any extra directories to look for libraries here.
 +#     Each directory must be seperated by a space.
 +#     Use forward slashes for directory separators.
 +#     For a directory that has spaces, enclose it in quotes.
 +EXTRALIBDIRS =
 +
 +
 +
 +#---------------- External Memory Options ----------------
 +
 +# 64 KB of external RAM, starting after internal RAM (ATmega128!),
 +# used for variables (.data/.bss) and heap (malloc()).
 +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
 +
 +# 64 KB of external RAM, starting after internal RAM (ATmega128!),
 +# only used for heap (malloc()).
 +#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
 +
 +EXTMEMOPTS =
 +
 +
 +
 +#---------------- Linker Options ----------------
 +#  -Wl,...:     tell GCC to pass this to linker.
 +#    -Map:      create map file
 +#    --cref:    add cross reference to  map file
 +LDFLAGS  = -Wl,-Map=$(TARGET).map,--cref
 +LDFLAGS += -Wl,--section-start=.text=$(BOOT_START)
 +LDFLAGS += -Wl,--relax
 +LDFLAGS += -Wl,--gc-sections
 +LDFLAGS += $(EXTMEMOPTS)
 +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
 +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
 +#LDFLAGS += -T linker_script.x
 +
 +
 +
 +#---------------- Programming Options (avrdude) ----------------
 +
 +# Programming hardware
 +# Type: avrdude -c ?
 +# to get a full listing.
 +#
 +AVRDUDE_PROGRAMMER = avrispmkII
 +
 +# com1 = serial port. Use lpt1 to connect to parallel port.
 +AVRDUDE_PORT = usb
 +
 +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
 +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
 +
 +
 +# Uncomment the following if you want avrdude's erase cycle counter.
 +# Note that this counter needs to be initialized first using -Yn,
 +# see avrdude manual.
 +#AVRDUDE_ERASE_COUNTER = -y
 +
 +# Uncomment the following if you do /not/ wish a verification to be
 +# performed after programming the device.
 +#AVRDUDE_NO_VERIFY = -V
 +
 +# Increase verbosity level.  Please use this when submitting bug
 +# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
 +# to submit bug reports.
 +#AVRDUDE_VERBOSE = -v -v
 +
 +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
 +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
 +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
 +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
 +
 +
 +
 +#---------------- Debugging Options ----------------
 +
 +# For simulavr only - target MCU frequency.
 +DEBUG_MFREQ = $(F_CPU)
 +
 +# Set the DEBUG_UI to either gdb or insight.
 +# DEBUG_UI = gdb
 +DEBUG_UI = insight
 +
 +# Set the debugging back-end to either avarice, simulavr.
 +DEBUG_BACKEND = avarice
 +#DEBUG_BACKEND = simulavr
 +
 +# GDB Init Filename.
 +GDBINIT_FILE = __avr_gdbinit
 +
 +# When using avarice settings for the JTAG
 +JTAG_DEV = /dev/com1
 +
 +# Debugging port used to communicate between GDB / avarice / simulavr.
 +DEBUG_PORT = 4242
 +
 +# Debugging host used to communicate between GDB / avarice / simulavr, normally
 +#     just set to localhost unless doing some sort of crazy debugging when
 +#     avarice is running on a different computer.
 +DEBUG_HOST = localhost
 +
 +
 +
 +#============================================================================
 +
 +
 +# Define programs and commands.
 +SHELL = sh
 +CC = avr-gcc
 +OBJCOPY = avr-objcopy
 +OBJDUMP = avr-objdump
 +SIZE = avr-size
 +AR = avr-ar rcs
 +NM = avr-nm
 +AVRDUDE = /Applications/avrdude -C /Applications/avrdude.conf -B 1
 +REMOVE = rm -f
 +REMOVEDIR = rm -rf
 +COPY = cp
 +WINSHELL = cmd
 +
 +
 +# Define Messages
 +# English
 +MSG_ERRORS_NONE = Errors: none
 +MSG_BEGIN = -------- begin --------
 +MSG_END = --------  end  --------
 +MSG_SIZE_BEFORE = Size before:
 +MSG_SIZE_AFTER = Size after:
 +MSG_COFF = Converting to AVR COFF:
 +MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
 +MSG_FLASH = Creating load file for Flash:
 +MSG_EEPROM = Creating load file for EEPROM:
 +MSG_EXTENDED_LISTING = Creating Extended Listing:
 +MSG_SYMBOL_TABLE = Creating Symbol Table:
 +MSG_LINKING = Linking:
 +MSG_COMPILING = Compiling C:
 +MSG_COMPILING_CPP = Compiling C++:
 +MSG_ASSEMBLING = Assembling:
 +MSG_CLEANING = Cleaning project:
 +MSG_CREATING_LIBRARY = Creating library:
 +
 +
 +
 +
 +# Define all object files.
 +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
 +
 +# Define all listing files.
 +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
 +
 +
 +# Compiler flags to generate dependency files.
 +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
 +
 +
 +# Combine all necessary flags and optional flags.
 +# Add target processor to flags.
 +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
 +ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
 +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
 +
 +
 +
 +
 +
 +# Default target.
 +all: begin gccversion sizebefore build sizeafter end
 +
 +# Change the build target to build a HEX file or a library.
 +build: elf hex eep lss sym
 +#build: lib
 +
 +
 +elf: $(TARGET).elf
 +hex: $(TARGET).hex
 +eep: $(TARGET).eep
 +lss: $(TARGET).lss
 +sym: $(TARGET).sym
 +LIBNAME=lib$(TARGET).a
 +lib: $(LIBNAME)
 +
 +
 +
 +# Eye candy.
 +# AVR Studio 3.x does not check make's exit code but relies on
 +# the following magic strings to be generated by the compile job.
 +begin:
 +	@echo
 +	@echo $(MSG_BEGIN)
 +
 +end:
 +	@echo $(MSG_END)
 +	@echo
 +
 +
 +# Display size of file.
 +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
 +ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
 +MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
 +FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
 +
 +
 +sizebefore:
 +	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
 +	2>/dev/null; echo; fi
 +
 +sizeafter:
 +	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
 +	2>/dev/null; echo; fi
 +
 +
 +
 +# Display compiler version information.
 +gccversion :
 +	@$(CC) --version
 +
 +
 +# Program the device.
 +program: $(TARGET).hex $(TARGET).eep
 +	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
 +
 +
 +# Generate avr-gdb config/init file which does the following:
 +#     define the reset signal, load the target file, connect to target, and set
 +#     a breakpoint at main().
 +gdb-config:
 +	@$(REMOVE) $(GDBINIT_FILE)
 +	@echo define reset >> $(GDBINIT_FILE)
 +	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
 +	@echo end >> $(GDBINIT_FILE)
 +	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
 +	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
 +ifeq ($(DEBUG_BACKEND),simulavr)
 +	@echo load  >> $(GDBINIT_FILE)
 +endif
 +	@echo break main >> $(GDBINIT_FILE)
 +
 +debug: gdb-config $(TARGET).elf
 +ifeq ($(DEBUG_BACKEND), avarice)
 +	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
 +	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
 +	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
 +	@$(WINSHELL) /c pause
 +
 +else
 +	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
 +	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
 +endif
 +	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
 +
 +
 +
 +
 +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
 +COFFCONVERT = $(OBJCOPY) --debugging
 +COFFCONVERT += --change-section-address .data-0x800000
 +COFFCONVERT += --change-section-address .bss-0x800000
 +COFFCONVERT += --change-section-address .noinit-0x800000
 +COFFCONVERT += --change-section-address .eeprom-0x810000
 +
 +
 +
 +coff: $(TARGET).elf
 +	@echo
 +	@echo $(MSG_COFF) $(TARGET).cof
 +	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
 +
 +
 +extcoff: $(TARGET).elf
 +	@echo
 +	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
 +	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
 +
 +
 +
 +# Create final output files (.hex, .eep) from ELF output file.
 +%.hex: %.elf
 +	@echo
 +	@echo $(MSG_FLASH) $@
 +	$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
 +
 +%.eep: %.elf
 +	@echo
 +	@echo $(MSG_EEPROM) $@
 +	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
 +	--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
 +
 +# Create extended listing file from ELF output file.
 +%.lss: %.elf
 +	@echo
 +	@echo $(MSG_EXTENDED_LISTING) $@
 +	$(OBJDUMP) -h -S -z $< > $@
 +
 +# Create a symbol table from ELF output file.
 +%.sym: %.elf
 +	@echo
 +	@echo $(MSG_SYMBOL_TABLE) $@
 +	$(NM) -n $< > $@
 +
 +
 +
 +# Create library from object files.
 +.SECONDARY : $(TARGET).a
 +.PRECIOUS : $(OBJ)
 +%.a: $(OBJ)
 +	@echo
 +	@echo $(MSG_CREATING_LIBRARY) $@
 +	$(AR) $@ $(OBJ)
 +
 +
 +# Link: create ELF output file from object files.
 +.SECONDARY : $(TARGET).elf
 +.PRECIOUS : $(OBJ)
 +%.elf: $(OBJ)
 +	@echo
 +	@echo $(MSG_LINKING) $@
 +	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
 +
 +
 +# Compile: create object files from C source files.
 +$(OBJDIR)/%.o : %.c
 +	@echo
 +	@echo $(MSG_COMPILING) $<
 +	$(CC) -c $(ALL_CFLAGS) $< -o $@
 +
 +
 +# Compile: create object files from C++ source files.
 +$(OBJDIR)/%.o : %.cpp
 +	@echo
 +	@echo $(MSG_COMPILING_CPP) $<
 +	$(CC) -c $(ALL_CPPFLAGS) $< -o $@
 +
 +
 +# Compile: create assembler files from C source files.
 +%.s : %.c
 +	$(CC) -S $(ALL_CFLAGS) $< -o $@
 +
 +
 +# Compile: create assembler files from C++ source files.
 +%.s : %.cpp
 +	$(CC) -S $(ALL_CPPFLAGS) $< -o $@
 +
 +
 +# Assemble: create object files from assembler source files.
 +$(OBJDIR)/%.o : %.S
 +	@echo
 +	@echo $(MSG_ASSEMBLING) $<
 +	$(CC) -c $(ALL_ASFLAGS) $< -o $@
 +
 +
 +# Create preprocessed source for use in sending a bug report.
 +%.i : %.c
 +	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
 +
 +
 +# Target: clean project.
 +clean: begin clean_list end
 +
 +clean_list :
 +	@echo
 +	@echo $(MSG_CLEANING)
 +	$(REMOVE) $(TARGET).hex
 +	$(REMOVE) $(TARGET).eep
 +	$(REMOVE) $(TARGET).cof
 +	$(REMOVE) $(TARGET).elf
 +	$(REMOVE) $(TARGET).map
 +	$(REMOVE) $(TARGET).sym
 +	$(REMOVE) $(TARGET).lss
 +	$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
 +	$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
 +	$(REMOVE) $(SRC:.c=.s)
 +	$(REMOVE) $(SRC:.c=.d)
 +	$(REMOVE) $(SRC:.c=.i)
 +	$(REMOVEDIR) .dep
 +
 +doxygen:
 +	@echo Generating Project Documentation \($(TARGET)\)...
 +	@doxygen Doxygen.conf
 +	@echo Documentation Generation Complete.
 +
 +clean_doxygen:
 +	rm -rf Documentation
 +
 +checksource:
 +	@for f in $(SRC) $(CPPSRC) $(ASRC); do \
 +		if [ -f $$f ]; then \
 +			echo "Found Source File: $$f" ; \
 +		else \
 +			echo "Source File Not Found: $$f" ; \
 +		fi; done 
 +
 +
 +# Create object files directory
 +$(shell mkdir $(OBJDIR) 2>/dev/null)
 +
 +
 +# Include the dependency files.
 +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
 +
 +
 +# Listing of phony targets.
 +.PHONY : all begin finish end sizebefore sizeafter gccversion \
 +build elf hex eep lss sym coff extcoff doxygen clean          \
 +clean_list clean_doxygen program debug gdb-config checksource
 +
 diff --git a/bootloaders/diskloader/DiskLoader-Leonardo.hex b/bootloaders/diskloader/DiskLoader-Leonardo.hex deleted file mode 100644 index 0d0c167..0000000 --- a/bootloaders/diskloader/DiskLoader-Leonardo.hex +++ /dev/null @@ -1,115 +0,0 @@ -:1078000011241FBECFEFDAE0DEBFCDBFFFC04101C4
 -:1078100042144505560455026403740300001E9586
 -:1078200087020110030000C18081C106C0FF0A0069
 -:107830000CA10185037508150026FF00954009017C
 -:107840008102954009029102C0040309041A033021
 -:1078500000300030003000300030003000300031A7
 -:1078600000370030003100380341007200640075B9
 -:107870000069006E006F0020004C0065006F006E14
 -:10788000006100720064006F00200062006F006FF2
 -:107890000074006C006F00610064006500720018E5
 -:1078A00003410072006400750069006E006F0020E3
 -:1078B000004C004C00430012010002020000404155
 -:1078C0002334000001000203011201000200000045
 -:1078D0004041233400000100020301090264000357
 -:1078E00001008032080B00020202010009040000BE
 -:1078F0000102020000052400100105240101010419
 -:107900002402020524060001070581031000400936
 -:10791000040100020A0000000705020240000007FF
 -:107920000583024000000904020001030000000971
 -:107930002101010001221E000705840340004000D0
 -:1079400020918A0130918B012C5F3F4F30938B0146
 -:1079500020938A01C901892F99278695982F803411
 -:1079600018F08FE7891B982F990F921710F44798FA
 -:107970000895479A08955D9A289A81E08093E000DF
 -:107980001092E200EE27FF27099408950F931F93AA
 -:10799000CF93DF93982FEB01042F10E088E760303E
 -:1079A000780730F411E083E0FB0180935700E895FD
 -:1079B000892F68E071E0402FF8D0112311F107B64C
 -:1079C00000FCFDCF402F4695FE01A8E0B1E020E08D
 -:1079D00031E009C08D919D910C0130935700E895DD
 -:1079E000112432962F5F2417A8F385E0FE018093BF
 -:1079F0005700E89507B600FCFDCF81E18093570062
 -:107A0000E895DF91CF911F910F91089588E10FB60E
 -:107A1000F89480936000109260000FBE5D9A289ADF
 -:107A200047983F9A209A559A90E890936100109257
 -:107A3000610081E885BF95BF9FD084E18093880174
 -:107A400080E180938901E0E0F0E0859194918F5F7F
 -:107A50009F4F19F081E080938F01EE24FF24BB2417
 -:107A6000B39454EFC52E51E0D52E13D2082F8EE0DB
 -:107A700098E7FC012491319602964491201711F069
 -:107A80002223B9F7109291011092900182E068E0F0
 -:107A900071E08BD0013479F4609108016058633053
 -:107AA00028F0683111F064E001C063E0C62FD0E037
 -:107AB000CF5DD7480EC0063571F480910801803340
 -:107AC00011F011E022C080910A01C82FD0E0C25EFF
 -:107AD000D74811E022C0053721F413E0CEE1D8E702
 -:107AE0001CC0053539F4E0900801F0900901EE0C56
 -:107AF000FF1C0AC0043631F482E0B701409109014D
 -:107B000045DF02C0043721F010E0C5E2D8E705C028
 -:107B100010910901E701E10EF11CBBD18097B1F48E
 -:107B200083E068E871E041E050E059D0112329F08A
 -:107B3000412F50E083E8BE0152D083E469E871E050
 -:107B400041E050E04CD0013509F08FCFD092910147
 -:107B5000C0929001B0928F01EE24FF2486CFFC01E9
 -:107B6000289884E680938D0104C08091F100819370
 -:107B700061506623D1F708951092910110929001FF
 -:107B800010928E0110928F0181E08093D70080EADD
 -:107B90008093D80082E189BD09B400FEFDCF80E961
 -:107BA0008093D8001092E0000895FB018093E900D3
 -:107BB00024E69BE611C08091E80085FFFCCF289861
 -:107BC00020938D018091F10081938091E80085FDE3
 -:107BD00002C09093E8004150442369F70895982F1C
 -:107BE000FB01282F207287708093E90064E63AE356
 -:107BF00017C08091E80085FFFCCF97FF02C08491F9
 -:107C000001C080813196211180E05D9860938C01E4
 -:107C10008093F1008091E80085FD02C03093E80078
 -:107C2000415050408FEF4F3F580719F796FF03C060
 -:107C30008AE38093E800089580919301813299F45A
 -:107C40005D9884E680938C0120E030E003C0808161
 -:107C50008093F100F901E050FF4F2F5F3F4F283034
 -:107C60003105A9F714C0803261F48091E80082FFE9
 -:107C7000FCCF80E091E067E072DF8BEF8093E8005B
 -:107C800006C0823221F4809194018093070181E043
 -:107C9000089520919501223289F1213081F480915B
 -:107CA000980190919901089711F420939A0180917D
 -:107CB0009A01882309F04FC0E9ECF8E74EC0223062
 -:107CC00021F484E6EBEDF8E71CC0233009F041C055
 -:107CD00080919401882319F4E9E4F8E73EC08230EA
 -:107CE00019F4E7E6F8E739C0833019F4EDE4F8E772
 -:107CF00034C0813071F5EFE9F8E72FC081E0EBE2A5
 -:107D0000F8E790919801382F981708F4392F90913F
 -:107D10008C0120E04EEF8091E8008570E1F38091C6
 -:107D2000E80082FD12C02F5F84915D988093F1007E
 -:107D3000822F8F7311F44093E800319694E6231755
 -:107D400050F390938C0181E0089590938C0180E032
 -:107D5000089580E00895E7EBF8E78491D2CF109280
 -:107D6000E9008091E80083FF61C082E991E068E06A
 -:107D7000F6DE82EF8093E8008091920187FF05C0D4
 -:107D80008091E80080FFFCCF03C08EEF8093E80075
 -:107D900080919301853051F48091E80080FFFCCF01
 -:107DA0008091940180688093E30039C08930E1F4C8
 -:107DB0008091940180938E01E7E2F8E791E031E051
 -:107DC00026E39093E9003093EB0084918093EC00DC
 -:107DD0002093ED009F5F3196953099F78EE7809361
 -:107DE000EA001092EA001BC0883049F490918E019D
 -:107DF0005D9884E680938C019093F10010C08823F5
 -:107E000039F45D9884E680938C011092F10007C0EC
 -:107E1000863011F43EDF01C00FDF882321F08EEFA2
 -:107E20008093E800089581E28093EB0008958091AB
 -:107E3000E1001092E100282F83FF0CC01092E900AE
 -:107E400081E08093EB001092EC0082E38093ED00E0
 -:107E500010928E0122FF1CC080918C01882331F08A
 -:107E6000815080938C01882309F45D9A80918D0163
 -:107E7000882331F0815080938D01882309F4289A5A
 -:107E800080918F01882321F410929101109290012A
 -:107E900008951F93CF93DF9312E0C0E9D1E05FDF35
 -:107EA000C6DF1093E9008091E80085FF13C0289891
 -:107EB00084E680938D019091F1008091E80085FD2A
 -:107EC00003C08BE68093E800892F90E0DF91CF918B
 -:107ED0001F91089580919001909191010197909345
 -:107EE0009101809390018091900190919101892B53
 -:0E7EF00009F441DDCE010197F1F722DDD0CF7C
 -:087EFE0000E10000000000009B
 -:040000030000780081
 -:00000001FF
 diff --git a/bootloaders/diskloader/Makefile b/bootloaders/diskloader/Makefile deleted file mode 100644 index 6ac3db3..0000000 --- a/bootloaders/diskloader/Makefile +++ /dev/null @@ -1,105 +0,0 @@ -############################################################################### -# Makefile for DiskLoader -############################################################################### - -## General Flags -PROJECT = DiskLoader -TARGET = DiskLoader.elf -CC = avr-gcc - -# BOARD2 -MCU = atmega32u4 -AVR_FREQ   = 16000000L - -# Specify the Arduino model using the assigned PID.  This is used by Descriptors.c
 -#   to set PID and product descriptor string
 -# Arduino Leonardo PID
 -ARDUINO_MODEL_PID = 0x0034
 -# Arduino Micro PID
 -#ARDUINO_MODEL_PID = 0x0035 - -# Change if your programmer is different -AVRDUDE_PROGRAMMER = avrispmkII -AVRDUDE_PORT = usb	    - -# program name should not be changed... -PROGRAM    = DiskLoader - -AVRDUDE = avrdude -AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) - -## Options common to compile, link and assembly rules -COMMON = -mmcu=$(MCU) - -override CFLAGS = -g -Wall -Os -mmcu=$(MCU) -DF_CPU=$(AVR_FREQ) -DARDUINO_MODEL_PID=$(ARDUINO_MODEL_PID) $(DEFS) -ffunction-sections -gdwarf-2 -fdata-sections -fno-split-wide-types - -## Assembly specific flags -ASMFLAGS = $(COMMON) -ASMFLAGS += $(CFLAGS) -ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 - -## Linker flags -LDFLAGS = $(COMMON) -LDFLAGS += -Wl,-gc-sections,-Map=DiskLoader.map,--section-start=.text=0x7800,--relax -LDFLAGS += -nodefaultlibs -nostartfiles - - -## Intel Hex file production flags -HEX_EEPROM_FLAGS = -j .eeprom -HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" -HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings - -## Objects explicitly added by the user -LINKONLYOBJECTS =  - -MODULES   := . -SRC_DIR   := $(addprefix src/,$(MODULES)) -BUILD_DIR := $(addprefix build/,$(MODULES)) - -SRC       := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp)) -OBJ       := $(patsubst src/%.cpp,build/%.o,$(SRC)) -DEP		  := $(OBJ:%.o=%.d) -INCLUDES  := $(addprefix -I,$(SRC_DIR)) - -vpath %.cpp $(SRC_DIR) - -.PHONY: all checkdirs clean - -all: checkdirs $(TARGET) DiskLoader.hex DiskLoader.lss size - --include $(DEP) - -checkdirs: $(BUILD_DIR) - -$(BUILD_DIR): -	@mkdir -p $@ - -clean: -	@rm -rf build/ -	@rm -f *.hex -	@rm -f *.elf -	@rm -f *.lss -	@rm -f *.map - -define make-goal -$1/%.o: %.cpp -	$(CC) $(INCLUDES) $(CFLAGS) -c $$< -MD -o $$@ -endef - -$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir)))) - -$(TARGET): $(OBJ) -	$(CC) $(LDFLAGS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) $^ -o $@ - -%.hex: $(TARGET) -	avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@ -	 -%.lss: $(TARGET) -	avr-objdump -h -S $< > $@ - -size: $(TARGET) -	@echo -#	@avr-size -C --mcu=${MCU} ${TARGET}.elf - -program: $(TARGET).hex -	$(AVRDUDE) $(AVRDUDE_FLAGS) -B 5 -u -U flash:w:$(TARGET).hex
\ No newline at end of file diff --git a/bootloaders/diskloader/src/DiskLoader.cpp b/bootloaders/diskloader/src/DiskLoader.cpp deleted file mode 100644 index 6580618..0000000 --- a/bootloaders/diskloader/src/DiskLoader.cpp +++ /dev/null @@ -1,239 +0,0 @@ - - -#include "Platform.h" - -//	This bootloader creates a composite Serial device -// -//	The serial interface supports a STK500v1 protocol that is very similar to optiboot -// -//	The bootloader will timeout and start the firmware after a few hundred milliseconds -//	if a usb connection is not detected. -//	 -//	The tweakier code is to keep the bootloader below 2k (no interrupt table, for example) - -extern "C" -void entrypoint(void) __attribute__ ((naked)) __attribute__ ((section (".vectors"))); -void entrypoint(void) -{ -	asm volatile ( -		"eor	r1,		r1\n"	// Zero register -		"out	0x3F,	r1\n"	// SREG -		"ldi	r28,	0xFF\n" -		"ldi	r29,	0x0A\n" -		"out	0x3E,	r29\n"	// SPH -		"out	0x3D,	r28\n"	// SPL -		"rjmp	main"			// Stack is all set up, start the main code -		::); -} - -u8 _flashbuf[128]; -u8 _inSync; -u8 _ok; -extern volatile u8 _ejected; -extern volatile u16 _timeout; - -void Program(u8 ep, u16 page, u8 count) -{ -	u8 write = page < 30*1024;		// Don't write over firmware please -	if (write) -		boot_page_erase(page); - -	Recv(ep,_flashbuf,count);		// Read while page is erasing - -	if (!write) -		return; - -	boot_spm_busy_wait();			// Wait until the memory is erased. - -	count >>= 1; -	u16* p = (u16*)page; -	u16* b = (u16*)_flashbuf; -	for (u8 i = 0; i < count; i++) -		boot_page_fill(p++, b[i]); - -    boot_page_write(page); -    boot_spm_busy_wait(); -    boot_rww_enable (); -} - - -int USBGetChar(); -#define getch USBGetChar - -#define HW_VER	 0x02 -#define SW_MAJOR 0x01 -#define SW_MINOR 0x10 - -#define STK_OK              0x10 -#define STK_INSYNC          0x14  // ' ' -#define CRC_EOP             0x20  // 'SPACE' -#define STK_GET_SYNC        0x30  // '0' - -#define STK_GET_PARAMETER   0x41  // 'A' -#define STK_SET_DEVICE      0x42  // 'B' -#define STK_SET_DEVICE_EXT  0x45  // 'E' -#define STK_LOAD_ADDRESS    0x55  // 'U' -#define STK_UNIVERSAL       0x56  // 'V' -#define STK_PROG_PAGE       0x64  // 'd' -#define STK_READ_PAGE       0x74  // 't' -#define STK_READ_SIGN       0x75  // 'u' - -extern const u8 _readSize[] PROGMEM; -const u8 _readSize[] =  -{ -	STK_GET_PARAMETER,	1, -	STK_SET_DEVICE,		20, -	STK_SET_DEVICE_EXT,	5, -	STK_UNIVERSAL,		4, -	STK_LOAD_ADDRESS,	2, -	STK_PROG_PAGE,		3, -	STK_READ_PAGE,		3, -	0,0 -}; - -extern const u8 _consts[] PROGMEM; -const u8 _consts[] =  -{ -	SIGNATURE_0, -	SIGNATURE_1, -	SIGNATURE_2, -	HW_VER,		// Hardware version -	SW_MAJOR,	// Software major version -	SW_MINOR,	// Software minor version -	0x03,		// Unknown but seems to be required by avr studio 3.56 -	0x00,		//  -}; - - -void USBInit(void); -int main(void) __attribute__ ((naked)); - -//	STK500v1 main loop, very similar to optiboot in protocol and implementation -int main() -{ -	wdt_disable(); -	TXLED0; -	RXLED0; -	LED0; -	BOARD_INIT(); -	USBInit(); - -	_inSync = STK_INSYNC; -	_ok = STK_OK; - -	if (pgm_read_word(0) != -1) -		_ejected = 1; - -	for(;;) -	{ -		u8* packet = _flashbuf; -		u16 address = 0; -		for (;;) -		{ -			u8 cmd = getch(); - -			//	Read packet contents -			u8 len; -			const u8* rs = _readSize; -			for(;;) -			{ -				u8 c = pgm_read_byte(rs++); -				len = pgm_read_byte(rs++); -				if (c == cmd || c == 0) -					break; -			} -			_timeout = 0; -			//	Read params -			Recv(CDC_RX,packet,len); - -			//	Send a response -			u8 send = 0; -			const u8* pgm = _consts+7;			// 0 -			if (STK_GET_PARAMETER == cmd) -			{ -				u8 i = packet[0] - 0x80; -				if (i > 2) -					i = (i == 0x18) ? 3 : 4;	// 0x80:HW_VER,0x81:SW_MAJOR,0x82:SW_MINOR,0x18:3 or 0 -				pgm = _consts + i + 3; -				send = 1; -			} - -			else if (STK_UNIVERSAL == cmd) -			{ -				if (packet[0] == 0x30) -					pgm = _consts + packet[2];	// read signature -				send = 1; -			} -			 -			//	Read signature bytes -			else if (STK_READ_SIGN == cmd) -			{ -				pgm = _consts; -				send = 3; -			} - -			else if (STK_LOAD_ADDRESS == cmd) -			{ -				address = *((u16*)packet);		// word addresses -				address += address; -			} - -			else if (STK_PROG_PAGE == cmd) -			{ -				Program(CDC_RX,address,packet[1]); -			} - -			else if (STK_READ_PAGE == cmd) -			{ -				send = packet[1]; -				pgm = (const u8*)address; -				address += send; // not sure of this is required -			} - -			// Check sync -			if (getch() != ' ') -				break; -			Transfer(CDC_TX,&_inSync,1); - -			// Send result -			if (send) -				Transfer(CDC_TX|TRANSFER_PGM,pgm,send);	// All from pgm memory - -			//	Send ok -			Transfer(CDC_TX|TRANSFER_RELEASE,&_ok,1); - -			if (cmd == 'Q') -				break; -		} -		_timeout = 500;		// wait a moment before exiting the bootloader - may need to finish responding to 'Q' for example -		_ejected = 1; -	} -} - -//	Nice breathing LED indicates we are in the firmware -u16 _pulse; -void LEDPulse() -{ -	_pulse += 4; -	u8 p = _pulse >> 9; -	if (p > 63) -		p = 127-p; -	p += p; -	if (((u8)_pulse) > p) -		LED0; -	else -		LED1; -} - -void Reboot() -{ -	TXLED0;		// switch off the RX and TX LEDs before starting the user sketch -	RXLED0; -	UDCON = 1;		// Detatch USB -	UDIEN = 0; -	asm volatile (	// Reset vector to run firmware -		"clr r30\n" -		"clr r31\n" -		"ijmp\n" -	::); -} diff --git a/bootloaders/diskloader/src/Platform.h b/bootloaders/diskloader/src/Platform.h deleted file mode 100644 index 04c5b79..0000000 --- a/bootloaders/diskloader/src/Platform.h +++ /dev/null @@ -1,51 +0,0 @@ - -#include <inttypes.h> -#include <avr/io.h> -#include <avr/pgmspace.h> -#include <avr/boot.h> -#include <util/delay.h> -#include <avr/interrupt.h> -#include <avr/wdt.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned long u32; - - -#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n)) -#define DISABLE_JTAG()  MCUCR = (1 << JTD) | (1 << IVCE) | (0 << PUD); MCUCR = (1 << JTD) | (0 << IVSEL) | (0 << IVCE) | (0 << PUD); - -#define USB_PID_LEONARDO 0x0034 -#define USB_PID_MICRO 0x0035 -#define USB_VID 0x2341	// arduino LLC vid -#define USB_PID ARDUINO_MODEL_PID	// passed in by Makefile - 0x0034 for Leonardo, 0x0035 for MIcro - -#define USB_SERIAL_STRING	'0','0','0','0','0','0','0','0','1','7','0','1' - -#define OEM_NAME		'l','e','o','n','a','r','d','o'					// 8 chars -#define BOARD_INIT()	DDRC |= (1<<7); DDRB |= (1<<0); DDRD |= (1<<5); CPU_PRESCALE(0); DISABLE_JTAG(); -#define LED0			PORTC &= ~(1<<7) -#define LED1			PORTC |= (1<<7) -#define TXLED0			PORTD |= (1<<5) -#define TXLED1			PORTD &= ~(1<<5) -#define RXLED0			PORTB |= (1<<0) -#define RXLED1			PORTB &= ~(1<<0) - -#define TRANSFER_PGM		0x80 -#define TRANSFER_RELEASE	0x40 -#define TRANSFER_ZERO		0x20 - -void Transfer(u8 ep, const u8* data, int len); -void Recv(u8 ep, u8* dst, u8 len); -void Program(u8 ep, u16 page, u8 count); - -#define CDC_ENABLED - -#include "USBCore.h" -#include "USBDesc.h" - - diff --git a/bootloaders/diskloader/src/USBCore.cpp b/bootloaders/diskloader/src/USBCore.cpp deleted file mode 100644 index 208121e..0000000 --- a/bootloaders/diskloader/src/USBCore.cpp +++ /dev/null @@ -1,510 +0,0 @@ - - -/* Copyright (c) 2010, Peter Barrett   -**   -** Permission to use, copy, modify, and/or distribute this software for   -** any purpose with or without fee is hereby granted, provided that the   -** above copyright notice and this permission notice appear in all copies.   -**  -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL   -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED   -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR   -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES   -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,   -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,   -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS   -** SOFTWARE.   -*/ - -#include "Platform.h" - -#define CDC_TX CDC_ENDPOINT_IN -#define CDC_RX CDC_ENDPOINT_OUT - -#define EP_TYPE_CONTROL				0x00 -#define EP_TYPE_BULK_IN				0x81 -#define EP_TYPE_BULK_OUT			0x80 -#define EP_TYPE_INTERRUPT_IN		0xC1 -#define EP_TYPE_INTERRUPT_OUT		0xC0 -#define EP_TYPE_ISOCHRONOUS_IN		0x41 -#define EP_TYPE_ISOCHRONOUS_OUT		0x40 - -/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ -#define TX_RX_LED_PULSE_MS 100 -u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ -u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ - -void Reboot(); - -//================================================================== -//================================================================== - -typedef struct -{ -	u32	dwDTERate; -	u8	bCharFormat; -	u8 	bParityType; -	u8 	bDataBits; -	u8	lineState; -} LineInfo; - -static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; - -//================================================================== -//================================================================== - -//	4 bytes of RAM -volatile u8 _usbConfiguration; -volatile u8 _ejected; -volatile u16 _timeout; - -static inline void WaitIN(void) -{ -	while (!(UEINTX & (1<<TXINI))); -} - -static inline void ClearIN(void) -{ -	UEINTX = ~(1<<TXINI); -} - -static inline void WaitOUT(void) -{ -	while (!(UEINTX & (1<<RXOUTI))) -		; -} - -static inline u8 WaitForINOrOUT() -{ -	while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI)))) -		; -	return (UEINTX & (1<<RXOUTI)) == 0; -} - -static inline void ClearOUT(void) -{ -	UEINTX = ~(1<<RXOUTI); -} - -static -void Send(volatile const u8* data, u8 count) -{ -	TXLED1;					// light the TX LED -	TxLEDPulse = TX_RX_LED_PULSE_MS; -	while (count--) -		UEDATX = *data++; -} - -void Recv(volatile u8* data, u8 count) -{ -	RXLED1;					// light the RX LED -	RxLEDPulse = TX_RX_LED_PULSE_MS; -	while (count--) -		*data++ = UEDATX; -} - -static inline u8 Recv8() -{ -	RXLED1;					// light the RX LED -	RxLEDPulse = TX_RX_LED_PULSE_MS; -	return UEDATX; -} - -static inline void Send8(u8 d) -{ -	TXLED1;					// light the TX LED -	TxLEDPulse = TX_RX_LED_PULSE_MS; -	UEDATX = d; -} - -static inline void SetEP(u8 ep) -{ -	UENUM = ep; -} - -static inline u8 FifoByteCount() -{ -	return UEBCLX; -} - -static inline u8 ReceivedSetupInt() -{ -	return UEINTX & (1<<RXSTPI); -} - -static inline void ClearSetupInt() -{ -	UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI)); -} - -static inline void Stall() -{ -	UECONX = (1<<STALLRQ) | (1<<EPEN); -} - -static inline u8 ReadWriteAllowed() -{ -	return UEINTX & (1<<RWAL); -} - -static inline u8 Stalled() -{ -	return UEINTX & (1<<STALLEDI); -} - -static inline u8 FifoFree() -{ -	return UEINTX & (1<<FIFOCON); -} - -static inline void ReleaseRX() -{ -	UEINTX = 0x6B;	// FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 -} - -static inline void ReleaseTX() -{ -	UEINTX = 0x3A;	// FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 -} - -static inline u8 FrameNumber() -{ -	return UDFNUML; -} - -//================================================================== -//================================================================== - -#define EP_SINGLE_64 0x32	// EP0 -#define EP_DOUBLE_64 0x36	// Other endpoints - -static void InitEP(u8 index, u8 type, u8 size) -{ -	UENUM = index; -	UECONX = 1; -	UECFG0X = type; -	UECFG1X = size; -} - -//	API -void USBInit(void) -{ -	_timeout = 0; -	_usbConfiguration = 0; -	_ejected = 0; -	 -	UHWCON = 0x01;						// power internal reg (don't need this?) -	USBCON = (1<<USBE)|(1<<FRZCLK);		// clock frozen, usb enabled -	PLLCSR = 0x12;						// Need 16 MHz xtal -	while (!(PLLCSR & (1<<PLOCK)))		// wait for lock pll -		; -	USBCON = ((1<<USBE)|(1<<OTGPADE));	// start USB clock -	UDCON = 0;							// enable attach resistor -} - -u8 USBGetConfiguration(void) -{ -	return _usbConfiguration; -} - -u8 HasData(u8 ep) -{ -	SetEP(ep); -	return ReadWriteAllowed();	// count in fifo -} - -int USBGetChar(); -void Recv(u8 ep, u8* dst, u8 len) -{ -	SetEP(ep); -	while (len--) -	{ -		while (!ReadWriteAllowed()) -			; -		*dst++ = Recv8(); -		if (!ReadWriteAllowed())	// release empty buffer -			ReleaseRX(); -	} -} - -//	Transmit a packet to endpoint -void Transfer(u8 ep, const u8* data, int len) -{ -	u8 zero = ep & TRANSFER_ZERO; -	SetEP(ep & 7); -	while (len--) -	{ -		while (!ReadWriteAllowed()) -			;	// TODO Check for STALL etc - -		u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0]; -		data++; -		if (zero) -			d = 0; -		Send8(d); - -		if (!ReadWriteAllowed()) -			ReleaseTX(); -	} -	if (ep & TRANSFER_RELEASE) -		ReleaseTX(); -} - -extern const u8 _initEndpoints[] PROGMEM; -const u8 _initEndpoints[] =  -{ -	0, - -#ifdef CDC_ENABLED -	EP_TYPE_INTERRUPT_IN,		// CDC_ENDPOINT_ACM -	EP_TYPE_BULK_OUT,			// CDC_ENDPOINT_OUT -	EP_TYPE_BULK_IN,			// CDC_ENDPOINT_IN -#endif - -	EP_TYPE_INTERRUPT_IN,		// HID_ENDPOINT_INT -}; - -static void InitEndpoints() -{ -	for (u8 i = 1; i < sizeof(_initEndpoints); i++) -	{ -		UENUM = i; -		UECONX = 1; -		UECFG0X = pgm_read_byte(_initEndpoints+i); -		UECFG1X = EP_DOUBLE_64; -	} -	UERST = 0x7E;	// And reset them -	UERST = 0; -} - -typedef struct -{ -	u8 bmRequestType; -	u8 bRequest; -	u8 wValueL; -	u8 wValueH; -	u16 wIndex; -	u16 wLength; -} Setup; -Setup _setup; - -//bool USBHook(Setup& setup) -bool USBHook() -{ -	Setup& setup = _setup; -	u8 r = setup.bRequest; - -	//	CDC Requests -	if (CDC_GET_LINE_CODING == r) -	{ -		Send((const volatile u8*)&_usbLineInfo,7); -	} - -	else if (CDC_SET_LINE_CODING ==  r) -	{ -		WaitOUT(); -		Recv((volatile u8*)&_usbLineInfo,7); -		ClearOUT(); -	} - -	else if (CDC_SET_CONTROL_LINE_STATE == r) -	{ -		_usbLineInfo.lineState = setup.wValueL; -	} - -	return true; -} - -extern const u8 _rawHID[] PROGMEM; -#define LSB(_x) ((_x) & 0xFF) -#define MSB(_x) ((_x) >> 8) - -#define RAWHID_USAGE_PAGE	0xFFC0 -#define RAWHID_USAGE		0x0C00 -#define RAWHID_TX_SIZE 64 -#define RAWHID_RX_SIZE 64 - -const u8 _rawHID[] = -{ -	//	RAW HID -	0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE),	// 30 -	0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), - -	0xA1, 0x01,				// Collection 0x01 -    0x85, 0x03,             // REPORT_ID (3) -	0x75, 0x08,				// report size = 8 bits -	0x15, 0x00,				// logical minimum = 0 -	0x26, 0xFF, 0x00,		// logical maximum = 255 - -	0x95, 64,				// report count TX -	0x09, 0x01,				// usage -	0x81, 0x02,				// Input (array) - -	0x95, 64,				// report count RX -	0x09, 0x02,				// usage -	0x91, 0x02,				// Output (array) -	0xC0					// end collection -}; - -u8 _cdcComposite = 0; - -bool SendDescriptor() -{ -	Setup& setup = _setup; -	u8 desc_length = 0; -	const u8* desc_addr = 0; - -	u8 t = setup.wValueH; -	if (0x22 == t) -	{ -		desc_addr = _rawHID; -		desc_length = sizeof(desc_length); -	} else if (USB_DEVICE_DESCRIPTOR_TYPE == t) -	{ -		if (setup.wLength == 8) -			_cdcComposite = 1; -		desc_addr = _cdcComposite ?  (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; -	} -	else if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) -	{ -		desc_addr = (const u8*)&USB_ConfigDescriptor; -		desc_length = sizeof(USB_ConfigDescriptor); -	} -	else if (USB_STRING_DESCRIPTOR_TYPE == t) -	{ -		if (setup.wValueL == 0) -			desc_addr = (const u8*)&STRING_LANGUAGE; -		else if (setup.wValueL == IPRODUCT)  -			desc_addr = (const u8*)&STRING_IPRODUCT; -		else if (setup.wValueL == ISERIAL) -			desc_addr = (const u8*)&STRING_SERIAL; -		else if (setup.wValueL == IMANUFACTURER) -			desc_addr = (const u8*)&STRING_IMANUFACTURER; -		else -			return false; -	} else  -		return false; - -	if (desc_length == 0) -		desc_length = pgm_read_byte(desc_addr); -	if ((u8)setup.wLength < desc_length)		// bit of a cheat limiting to 255 bytes TODO (saved 8 bytes) -		desc_length = (u8)setup.wLength; - -	//	Send descriptor -	//	EP0 is 64 bytes long -	//	RWAL and FIFOCON don't work on EP0 -	u8 n = 0; -	do -	{ -		if (!WaitForINOrOUT()) -			return false; -		Send8(pgm_read_byte(&desc_addr[n++])); -		u8 clr = n & 0x3F; -		if (!clr) -			ClearIN();	// Fifo is full, release this packet -	} while (n < desc_length); -	return true; -} - -void USBSetupInterrupt() -{ -    SetEP(0); -	if (!ReceivedSetupInt()) -		return; - -	Setup& setup = _setup;	// global saves ~30 bytes -	Recv((u8*)&setup,8); -	ClearSetupInt(); - -	if (setup.bmRequestType & DEVICETOHOST) -		WaitIN(); -	else -		ClearIN(); - -    bool ok = true; -	u8 r = setup.bRequest; -	if (SET_ADDRESS == r) -	{ -		WaitIN(); -		UDADDR = setup.wValueL | (1<<ADDEN); -	} -	else if (SET_CONFIGURATION == r) -	{ -		_usbConfiguration = setup.wValueL; -		InitEndpoints(); -	} -	else if (GET_CONFIGURATION == r) -	{ -		Send8(_usbConfiguration); -	} -	else if (GET_STATUS == r) -	{ -		Send8(0);		// All good as far as I know -	} -	else if (GET_DESCRIPTOR == r) -	{ -		ok = SendDescriptor(); -	} -	else -	{ -		ok = USBHook(); -	} - -	if (ok) -		ClearIN(); -	else -		Stall(); -} - -void USBGeneralInterrupt() -{ -	u8 udint = UDINT; -	UDINT = 0; - -	//	End of Reset -	if (udint & (1<<EORSTI)) -	{ -		InitEP(0,EP_TYPE_CONTROL,EP_SINGLE_64);	// init ep0 -		_usbConfiguration = 0;			// not configured yet -	} - -	//	Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too -	if (udint & (1<<SOFI)) -	{ -		// check whether the one-shot period has elapsed.  if so, turn off the LED -		if (TxLEDPulse && !(--TxLEDPulse)) -			TXLED0; -		if (RxLEDPulse && !(--RxLEDPulse)) -			RXLED0; -		 -		if (!_ejected) -			_timeout = 0; -	} -} - -void LEDPulse(); -int USBGetChar() -{ -	for(;;) -	{ -		USBSetupInterrupt(); -		USBGeneralInterrupt(); - -		//	Read a char -		if (HasData(CDC_RX)) -		{ -			u8 c = Recv8(); -			if (!ReadWriteAllowed()) -				ReleaseRX(); -			return c; -		}  - -		if (!--_timeout) { -			Reboot();	// USB not connected, run firmware -		} -		 -		_delay_us(100);	// stretch out the bootloader period to about 5 seconds after enumeration -		LEDPulse(); -	} -	return -1; -} diff --git a/bootloaders/diskloader/src/USBCore.h b/bootloaders/diskloader/src/USBCore.h deleted file mode 100644 index 537c0ec..0000000 --- a/bootloaders/diskloader/src/USBCore.h +++ /dev/null @@ -1,246 +0,0 @@ - -// Copyright (c) 2010, Peter Barrett  -/* -** Permission to use, copy, modify, and/or distribute this software for   -** any purpose with or without fee is hereby granted, provided that the   -** above copyright notice and this permission notice appear in all copies.   -**   -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL   -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED   -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR   -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES   -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,   -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,   -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS   -** SOFTWARE.   -*/ - -#ifndef __USBCORE_H__ -#define __USBCORE_H__ - -#define GET_STATUS			0 -#define CLEAR_FEATURE		1 -#define SET_FEATURE			3 -#define SET_ADDRESS			5 -#define GET_DESCRIPTOR		6 -#define GET_CONFIGURATION	8 -#define SET_CONFIGURATION	9 -#define GET_INTERFACE		10 -#define SET_INTERFACE		11 - -// bmRequestType -#define HOSTTODEVICE	0x00 -#define DEVICETOHOST	0x80 -#define STANDARD		0x00 -#define CLASS			0x20 -#define VENDOR			0x40 -#define DEVICE			0x00 -#define INTERFACE		0x01 -#define ENDPOINT		0x02 -#define OTHER			0x03 - -#define CDC_SET_LINE_CODING		0x20 -#define CDC_GET_LINE_CODING		0x21 -#define CDC_SET_CONTROL_LINE_STATE	0x22 - -//	Descriptors - -#define USB_DEVICE_DESC_SIZE 18 -#define USB_CONFIGUARTION_DESC_SIZE 9 -#define USB_INTERFACE_DESC_SIZE 9 -#define USB_ENDPOINT_DESC_SIZE 7 - -#define USB_DEVICE_DESCRIPTOR_TYPE             1 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE      2 -#define USB_STRING_DESCRIPTOR_TYPE             3 -#define USB_INTERFACE_DESCRIPTOR_TYPE          4 -#define USB_ENDPOINT_DESCRIPTOR_TYPE           5 - -#define USB_DEVICE_CLASS_COMMUNICATIONS        0x02 -#define USB_DEVICE_CLASS_HUMAN_INTERFACE       0x03 -#define USB_DEVICE_CLASS_STORAGE               0x08 -#define USB_DEVICE_CLASS_VENDOR_SPECIFIC       0xFF - -#define USB_CONFIG_POWERED_MASK                0x40 -#define USB_CONFIG_BUS_POWERED                 0x80 -#define USB_CONFIG_SELF_POWERED                0xC0 -#define USB_CONFIG_REMOTE_WAKEUP               0x20 - -// bMaxPower in Configuration Descriptor -#define USB_CONFIG_POWER_MA(mA)                ((mA)/2) - -// bEndpointAddress in Endpoint Descriptor -#define USB_ENDPOINT_DIRECTION_MASK            0x80 -#define USB_ENDPOINT_OUT(addr)                 ((addr) | 0x00) -#define USB_ENDPOINT_IN(addr)                  ((addr) | 0x80) - -#define USB_ENDPOINT_TYPE_MASK                 0x03 -#define USB_ENDPOINT_TYPE_CONTROL              0x00 -#define USB_ENDPOINT_TYPE_ISOCHRONOUS          0x01 -#define USB_ENDPOINT_TYPE_BULK                 0x02 -#define USB_ENDPOINT_TYPE_INTERRUPT            0x03 - -#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) - -#define CDC_V1_10                               0x0110 -#define CDC_COMMUNICATION_INTERFACE_CLASS       0x02 - -#define CDC_CALL_MANAGEMENT                     0x01 -#define CDC_ABSTRACT_CONTROL_MODEL              0x02 -#define CDC_HEADER                              0x00 -#define CDC_ABSTRACT_CONTROL_MANAGEMENT         0x02 -#define CDC_UNION                               0x06 -#define CDC_CS_INTERFACE                        0x24 -#define CDC_CS_ENDPOINT                         0x25 -#define CDC_DATA_INTERFACE_CLASS                0x0A - - -//	Device -typedef struct { -	u8 len;				// 18 -	u8 dtype;			// 1 USB_DEVICE_DESCRIPTOR_TYPE -	u16 usbVersion;		// 0x200 -	u8	deviceClass; -	u8	deviceSubClass; -	u8	deviceProtocol; -	u8	packetSize0;	// Packet 0 -	u16	idVendor; -	u16	idProduct; -	u16	deviceVersion;	// 0x100 -	u8	iManufacturer; -	u8	iProduct; -	u8	iSerialNumber; -	u8	bNumConfigurations; -} DeviceDescriptor; - -//	Config -typedef struct { -	u8	len;			// 9 -	u8	dtype;			// 2 -	u16 clen;			// total length -	u8	numInterfaces; -	u8	config; -	u8	iconfig; -	u8	attributes; -	u8	maxPower; -} ConfigDescriptor; - -//	String - -//	Interface -typedef struct -{ -	u8 len;		// 9 -	u8 dtype;	// 4 -	u8 number; -	u8 alternate; -	u8 numEndpoints; -	u8 interfaceClass; -	u8 interfaceSubClass; -	u8 protocol; -	u8 iInterface; -} InterfaceDescriptor; - -//	Endpoint -typedef struct -{ -	u8 len;		// 7 -	u8 dtype;	// 5 -	u8 addr; -	u8 attr; -	u16 packetSize; -	u8 interval; -} EndpointDescriptor; - -// Interface Association Descriptor -// Used to bind 2 interfaces together in CDC compostite device -typedef struct -{ -	u8 len;				// 8 -	u8 dtype;			// 11 -	u8 firstInterface; -	u8 interfaceCount; -	u8 functionClass; -	u8 funtionSubClass; -	u8 functionProtocol; -	u8 iInterface; -} IADDescriptor; - -//	CDC CS interface descriptor -typedef struct -{ -	u8 len;		// 5 -	u8 dtype;	// 0x24 -	u8 subtype; -	u8 d0; -	u8 d1; -} CDCCSInterfaceDescriptor; - -typedef struct -{ -	u8 len;		// 4 -	u8 dtype;	// 0x24 -	u8 subtype; -	u8 d0; -} CDCCSInterfaceDescriptor4; - -typedef struct  -{ -	IADDescriptor				iad;	// Only needed on compound device - -	//	Control -	InterfaceDescriptor			cif;	//  -	CDCCSInterfaceDescriptor	header; -	CDCCSInterfaceDescriptor	callManagement; -	CDCCSInterfaceDescriptor4	controlManagement; -	CDCCSInterfaceDescriptor	functionalDescriptor; -	EndpointDescriptor			cifin; - -	//	Data -	InterfaceDescriptor			dif; -	EndpointDescriptor			in; -	EndpointDescriptor			out; -} CDCDescriptor; - -typedef struct -{ -	u8 len;			// 9 -	u8 dtype;		// 0x21 -	u8 addr; -	u8	versionL;	// 0x101 -	u8	versionH;	// 0x101 -	u8	country; -	u8	desctype;	// 0x22 report -	u8	descLenL; -	u8	descLenH; -} HIDDescDescriptor; - -typedef struct  -{ -	InterfaceDescriptor			hid; -	HIDDescDescriptor			desc; -	EndpointDescriptor			in; -} HIDDescriptor; - -#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ -	{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } - -#define D_CONFIG(_totalLength,_interfaces) \ -	{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(100) } - -#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ -	{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } - -#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ -	{ 7, 5, _addr,_attr,_packetSize, _interval } - -#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ -	{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } - -#define D_HIDREPORT(_descriptorLength) \ -	{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } - -#define D_CDCCS(_subtype,_d0,_d1)	{ 5, 0x24, _subtype, _d0, _d1 } -#define D_CDCCS4(_subtype,_d0)		{ 4, 0x24, _subtype, _d0 } - -#endif
\ No newline at end of file diff --git a/bootloaders/diskloader/src/USBDesc.cpp b/bootloaders/diskloader/src/USBDesc.cpp deleted file mode 100644 index ade072a..0000000 --- a/bootloaders/diskloader/src/USBDesc.cpp +++ /dev/null @@ -1,87 +0,0 @@ - - -/* Copyright (c) 2011, Peter Barrett   -**   -** Permission to use, copy, modify, and/or distribute this software for   -** any purpose with or without fee is hereby granted, provided that the   -** above copyright notice and this permission notice appear in all copies.   -**  -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL   -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED   -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR   -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES   -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,   -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,   -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS   -** SOFTWARE.   -*/ - -#include "Platform.h" - -//==================================================================================================== -//==================================================================================================== -//	Actual device descriptors - -const u16 STRING_LANGUAGE[2] = { -	(3<<8) | (2+2), -	0x0409	// English -}; - -const u16 STRING_SERIAL[13] = { -	(3<<8) | (2+2*12), -	USB_SERIAL_STRING -}; - -const u16 STRING_IPRODUCT[28] = { -	(3<<8) | (2+2*27), -#if USB_PID == USB_PID_LEONARDO	 -	'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o',' ','b','o','o','t','l','o','a','d','e','r' -#elif USB_PID == USB_PID_MICRO -	'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ','b','o','o','t','l','o','a','d','e','r',' ',' ',' ' -#endif -}; - -const u16 STRING_IMANUFACTURER[12] = { -	(3<<8) | (2+2*11), -	'A','r','d','u','i','n','o',' ','L','L','C' -}; - - -//#ifdef CDC_ENABLED -DeviceDescriptor USB_DeviceDescriptorA = D_DEVICE(0X02,0X00,0X00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1); -//#else -DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1); -//#endif - - -Config USB_ConfigDescriptor = -{ -	D_CONFIG(sizeof(Config),INTERFACE_COUNT), - -#ifdef CDC_ENABLED -	//	CDC -	{ -		D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), - -		//	CDC communication interface -		D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), -		D_CDCCS(CDC_HEADER,0x10,0x01),								// Header (1.10 bcd) -		D_CDCCS(CDC_CALL_MANAGEMENT,1,1),							// Device handles call management -		D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,2),				// SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported -		D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE),	// Communication interface is master, data interface is slave 0 -		D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), - -		//	CDC data interface -		D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), -		D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), -		D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) -	}, -#endif -	// HID -	{ -		D_INTERFACE(HID_INTERFACE,1,3,0,0), -		D_HIDREPORT(30), -		D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x40) -	} -}; - diff --git a/bootloaders/diskloader/src/USBDesc.h b/bootloaders/diskloader/src/USBDesc.h deleted file mode 100644 index a970fa4..0000000 --- a/bootloaders/diskloader/src/USBDesc.h +++ /dev/null @@ -1,65 +0,0 @@ - - -/* Copyright (c) 2011, Peter Barrett   -**   -** Permission to use, copy, modify, and/or distribute this software for   -** any purpose with or without fee is hereby granted, provided that the   -** above copyright notice and this permission notice appear in all copies.   -**  -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL   -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED   -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR   -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES   -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,   -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,   -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS   -** SOFTWARE.   -*/ - - -#ifdef CDC_ENABLED - -#define CDC_ACM_INTERFACE	0	// CDC ACM -#define CDC_DATA_INTERFACE	1	// CDC Data -#define CDC_ENDPOINT_ACM	1 -#define CDC_ENDPOINT_OUT	2 -#define CDC_ENDPOINT_IN		3 - -#define HID_INTERFACE		2	// HID Interface -#define HID_ENDPOINT_INT	4 - -#define INTERFACE_COUNT		3	// 2 for cdc + 1 for hid - -#else  - -#define HID_INTERFACE		2	// HID Interface -#define HID_ENDPOINT_INT	4 - -#define INTERFACE_COUNT		1	// 1 for hid - -#endif - -typedef struct -{ -	ConfigDescriptor	config; -#ifdef CDC_ENABLED -	CDCDescriptor		cdc; -#endif -	HIDDescriptor		hid; -} Config; - -extern Config USB_ConfigDescriptor PROGMEM; -extern DeviceDescriptor USB_DeviceDescriptor PROGMEM; -extern DeviceDescriptor USB_DeviceDescriptorA PROGMEM; - -extern const u16 STRING_LANGUAGE[2] PROGMEM; -extern const u16 STRING_IPRODUCT[28] PROGMEM; -extern const u16 STRING_IMANUFACTURER[12] PROGMEM; -extern const u16 STRING_SERIAL[13] PROGMEM; - -#define IMANUFACTURER	1 -#define IPRODUCT		2 -#define ISERIAL			3 - -#define CDC_TX CDC_ENDPOINT_IN -#define CDC_RX CDC_ENDPOINT_OUT
\ No newline at end of file  | 
