commit 73f05b45c81f32d521752fa6eb5da782cbe4503a Author: Sin Shimozono Date: Thu Jul 10 10:52:36 2014 +0900 My first diff --git a/floppy-emu-1.0Q-F13/femu.bin b/floppy-emu-1.0Q-F13/femu.bin new file mode 100755 index 0000000..9774539 Binary files /dev/null and b/floppy-emu-1.0Q-F13/femu.bin differ diff --git a/floppy-emu-1.0Q-F13/firmware.xvf b/floppy-emu-1.0Q-F13/firmware.xvf new file mode 100755 index 0000000..f0ff052 Binary files /dev/null and b/floppy-emu-1.0Q-F13/firmware.xvf differ diff --git a/floppy-emu-1.0Q-F13/floppyemu.hex b/floppy-emu-1.0Q-F13/floppyemu.hex new file mode 100755 index 0000000..5a58de4 --- /dev/null +++ b/floppy-emu-1.0Q-F13/floppyemu.hex @@ -0,0 +1,2133 @@ +:100000004CC4000079C4000077C4000075C400002F +:100010000C94990F71C400000C94250C0C94710B76 +:100020006BC4000069C4000067C4000065C4000020 +:1000300063C4000061C400005FC400005DC4000030 +:100040005BC4000059C400000C94F72155C40000A3 +:1000500053C4000051C400004FC400004DC4000050 +:100060004BC4000049C4000047C4000045C4000060 +:1000700043C4000041C400003FC400003DC4000070 +:100080003BC4000039C4000037C4000000000C006D +:100090001800240030003C004800540060006C0050 +:1000A0007800840090009C00A800B400C000CB0041 +:1000B000D600E100EC00F70002010D011801230158 +:1000C0002E01390144014F015A01650170017A0185 +:1000D00084018E019801A201AC01B601C001CA01E0 +:1000E000D401DE01E801F201FC010602100219024E +:1000F00022022B0234023D0246024F0258026102E4 +:100100006A0273027C0285028E029702A002A80294 +:10011000B002B802C002C802D002D802E002E8026F +:10012000F002F80200030803100318030C0C0C0C77 +:100130000C0C0C0C0C0C0C0C0C0C0C0C0B0B0B0B03 +:100140000B0B0B0B0B0B0B0B0B0B0B0B0A0A0A0A03 +:100150000A0A0A0A0A0A0A0A0A0A0A0A0909090903 +:100160000909090909090909090909090808080803 +:1001700008080808080808080808080896979A9BBD +:100180009D9E9FA6A7ABACADAEAFB2B3B4B5B6B7AC +:10019000B9BABBBCBDBEBFCBCDCECFD3D6D7D9DAD3 +:1001A000DBDCDDDEDFE5E6E7E9EAEBECEDEEEFF2E6 +:1001B000F3F4F5F6F7F9FAFBFCFDFEFF0001FFFF93 +:1001C0000203FF040506FFFFFFFFFFFF0708FFFF15 +:1001D000FF090A0B0C0DFFFF0E0F10111213FF1475 +:1001E00015161718191AFFFFFFFFFFFFFFFFFFFF8C +:1001F000FF1BFF1C1D1EFFFFFF1FFFFF2021FF2213 +:10020000232425262728FFFFFFFFFF292A2BFF2C69 +:100210002D2E2F303132FFFF333435363738FF394A +:100220003A3B3C3D3E3F0000211042206330844079 +:10023000A550C660E770088129914AA16BB18CC1B5 +:10024000ADD1CEE1EFF13112100273325222B5522C +:100250009442F772D662399318837BB35AA3BDD305 +:100260009CC3FFF3DEE36224433420040114E664FC +:10027000C774A44485546AA54BB528850995EEE555 +:10028000CFF5ACC58DD55336722611163006D7760C +:10029000F6669556B4465BB77AA719973887DFF7A5 +:1002A000FEE79DD7BCC7C448E5588668A7784008D4 +:1002B000611802282338CCC9EDD98EE9AFF94889F5 +:1002C00069990AA92BB9F55AD44AB77A966A711A6C +:1002D000500A333A122AFDDBDCCBBFFB9EEB799B45 +:1002E000588B3BBB1AABA66C877CE44CC55C222CBC +:1002F000033C600C411CAEED8FFDECCDCDDD2AAD95 +:100300000BBD688D499D977EB66ED55EF44E133E4B +:10031000322E511E700E9FFFBEEFDDDFFCCF1BBFE4 +:100320003AAF599F788F8891A981CAB1EBA10CD1BE +:100330002DC14EF16FE18010A100C230E3200450C6 +:10034000254046706760B9839893FBA3DAB33DC339 +:100350001CD37FE35EF3B1029012F322D232354216 +:10036000145277625672EAB5CBA5A89589856EF5C9 +:100370004FE52CD50DC5E234C324A0148104667466 +:10038000476424540544DBA7FAB79987B8975FE719 +:100390007EF71DC73CD7D326F2369106B0165766B6 +:1003A0007676154634564CD96DC90EF92FE9C899A1 +:1003B000E9898AB9ABA94458654806782768C01806 +:1003C000E1088238A3287DCB5CDB3FEB1EFBF98B79 +:1003D000D89BBBAB9ABB754A545A376A167AF10A56 +:1003E000D01AB32A923A2EFD0FED6CDD4DCDAABD89 +:1003F0008BADE89DC98D267C076C645C454CA23CA6 +:10040000832CE01CC10C1FEF3EFF5DCF7CDF9BAF58 +:10041000BABFD98FF89F176E367E554E745E932EF5 +:10042000B23ED10EF01E787C3C1E1E1E1E1E3E3EAD +:10043000FEFCFCF8F0E0800000000000000000007E +:1004400080E0FFFFFFFF7F1F00000000FFFFFFFFB6 +:10045000FF07070303010100000000000078FCFC17 +:10046000FCFC7800000000000000000000C020102C +:1004700008080402020201010101F00E010000005F +:10048000000000607070000000000F70800000002D +:100490000000804020101008080800000003040835 +:1004A000101020404040808080800F70800000004D +:1004B0000000081020404080808020202020202044 +:1004C000202020202020202020202020202020004C +:1004D0002049646C6500205265616400577269743C +:1004E0006500547261636B202020205369646500AD +:1004F000313434304B204469736B436F7079206919 +:100500006D616765003830304B204469736B436F11 +:10051000707920696D616765003430304B20446923 +:10052000736B436F707920696D6167650031343496 +:10053000304B2072617720696D616765003830301B +:100540004B2072617720696D616765003430304BF4 +:100550002072617720696D61676500696D6167650B +:10056000206E6F7420636F6E746967756F757300AA +:100570006572726F72206F70656E696E6720696D4B +:1005800061676500504C454153452057414954002F +:100590003130313031303130313031302E2E2E008B +:1005A0003031303130313031303130313031300074 +:1005B000202020205550444154494E472043504C60 +:1005C000442020202000436F6E74726173743A20BF +:1005D0000053454C4543543A2053617665004E45DF +:1005E00058543A204461726B657200505245563A35 +:1005F000204C69676874657200626567696E0052B5 +:10060000656C6561736520627574746F6E732074B8 +:100610006F00434F4E54524153542041444A555366 +:10062000544D454E54004170702056657273696F89 +:100630006E20312E302051002020202020464C4FAB +:1006400050505920454D5520202020202000534453 +:100650002052454144204552524F52205200666973 +:10066000726D776172652E78766600436F756C6483 +:10067000206E6F74206F70656E00434845434B20B9 +:1006800050494E53202D2044454641554C5400437B +:100690004845434B2050494E20434C4B4F2D48007A +:1006A000434845434B2050494E20434C4B4F2D4C23 +:1006B00000434845434B2050494E20524553455432 +:1006C00000434845434B2050494E20454A4543543A +:1006D00000434845434B2050494E20435552525FFA +:1006E0005349444500434845434B2050494E20520E +:1006F000445F41434B00434845434B2050494E2003 +:100700005752455100434845434B2050494E2053D2 +:100710005445505F52455100434845434B20504992 +:100720004E20535445505F44495200434845434B83 +:100730002050494E53202D20414C4C0046415441FD +:100740004C204552524F5220202020202020202093 +:1007500020005752495445204552524F52202020E4 +:10076000202020202020200000000000170003008F +:10077000031F0A1F0A1F050904120F171C00030399 +:10078000000E11110E00050205040E0410080004ED +:1007900004040010001804031E110F021F00191595 +:1007A0001215150A07041F1715091E151D19050333 +:1007B0001A150B17150F000A00040C04040E1F0A6B +:1007C0000A0A1F0E040115030E15161E051E1F151D +:1007D0000A0E11111F110E1F15151F05050E151DEF +:1007E0001F041F111F1108100F1F041B1F10101FC3 +:1007F000061F1F0E1F0E110E1F05020E191E1F0DC4 +:1008000016121509011F010F101F0718071F0C1FD3 +:100810001B041B031C031915131F101002040810DE +:10082000101F0406041010100003031A161C1F12D8 +:100830000C0C12120C121F0C1A16041E050C2A1E88 +:100840001F021C001D0010201D1F0C12111F101E66 +:100850000E1E1E021C0C120C3E120C0C123E1C0230 +:1008600002141E0A021F120E101E0E180E1E1C1E4F +:10087000120C1206281E1A1F16041B11001F00114D +:100880001B04080C047C3C3E5E2B3D3F2F5B5D3B14 +:100890002C2A225C0000E221E62111241FBECFEFAA +:1008A000D0E4DEBFCDBF13E0A0E0B1E0E6EAF2E8BD +:1008B00000E00BBF02C007900D92A636B107D9F732 +:1008C00018E3A6E6B3E001C01D92AB32B107E1F731 +:1008D00018E000E0C8E9D8E040E006C022974109EE +:1008E000FE014BBF0E94F93DC639D1074007B1F761 +:1008F0000E94791C0C94424183CB2F923F924F92DD +:100900005F926F927F928F929F92AF92BF92CF929F +:10091000DF92EF92FF920F931F93DF93CF93CDB7A8 +:10092000DEB72D970FB6F894DEBF0FBECDBF8B019B +:100930004A013E010894611C711CD301E4E2F1E01C +:100940002DE001900D922150E1F7BB244424AA240C +:1009500052E8552E42E2E42EF12CE80EF91E3EE05C +:10096000C32ED12CCC0EDD1E22E8222E312C280CD9 +:10097000391CC701B80140E250E00E94482980328A +:100980009105A1F4D8011B968C911B9790E09C01D6 +:100990002F7330702F30310559F183FD23C0F801DA +:1009A0008081853E19F1882309F05AC0D4011C9238 +:1009B00080E02D960FB6F894DEBF0FBECDBFCF916D +:1009C000DF911F910F91FF90EF90DF90CF90BF903C +:1009D000AF909F908F907F906F905F904F903F90DF +:1009E0002F900895F8018081882301F3BB24C1CFA3 +:1009F000BB2021F58C91982F907E903409F0B9CFCF +:100A00009FE1A92EA8221D964C90F1011082A5E726 +:100A1000B0E085E7582EF301AD01480D591D8191D5 +:100A20009801280F311DD9018C91DA018D93AD0108 +:100A3000EC15FD05A1F7BB24B3949BCFD8018C9195 +:100A4000AA948A1599F61D968C911D97841571F6B6 +:100A5000552009F48ECFB3EF5B0EA52DB0E0DBCFB0 +:100A60008E3221F2BB2081F031962BE090E001C064 +:100A70008191392F3795332737959695932B980F7A +:100A80002150B1F7941531F0C801B4010E948828B3 +:100A900081E08FCFFA2DF130B9F7452D50E0433882 +:100AA0005105B4F79A0160E080E090E0880D991D4F +:100AB000280D391DD9012C91FC0120836F5F862FF1 +:100AC00090E09C01240F351F233831057CF381E031 +:100AD00070CFEF92FF920F931F93DF93CF93CDB719 +:100AE000DEB7A9970FB6F894DEBF0FBECDBFFC01ED +:100AF000DB018C918E32A9F1838590E08871907032 +:100B00008031910509F466C0009759F5848D958D63 +:100B1000A68DB78D803020E4920726E0A20720E062 +:100B2000B20709F459C0803020E892072CE0A207F0 +:100B300020E0B20709F454C0803020E8920726E193 +:100B4000A20720E0B20709F449C081509044A640B2 +:100B5000B0408F3F2FE2920721E1A20720E0B207C9 +:100B600078F020E0822FA9960FB6F894DEBF0FBE72 +:100B7000CDBFCF91DF911F910F91FF90EF9008951E +:100B8000CF017E010894E11CF11CB7010E94882866 +:100B90001E86198A8E01025F1F4FC801B70141E00E +:100BA0000E94B32E882371F0C80163EC73E340E028 +:100BB00052E00E944829C8010E94B22B809115344E +:100BC000813081F08989882361F2C8010E94B22BAB +:100BD00020E0C8CF21E0C6CF23E0C4CF25E0C2CFBC +:100BE00024E0C0CF80911634882361F780910434CB +:100BF00090E0A0E0B0E0BA2FA92F982F882720918D +:100C00000534820F911DA11DB11DB695A79597952D +:100C10008795B695A79597958795803921E0920796 +:100C200020E0A20720E0B207F1F0803223E0920733 +:100C300020E0A20720E0B207A1F0803A25E0920769 +:100C400020E0A20720E0B20709F0BCCF28E08989A4 +:100C5000882309F487CFC80129A70E94B22B29A5B0 +:100C600081CF27E0F4CF26E0F2CF2F923F924F9230 +:100C70005F926F927F928F929F92AF92BF92CF922C +:100C8000DF92EF92FF920F931F93DF93CF93CDB735 +:100C9000DEB7C05FD0400FB6F894DEBF0FBECDBF49 +:100CA0007C011092670310926603829640E050E048 +:100CB000BA010E94CA2A03E4C02ED12CCC0EDD1E3C +:100CC00013E6A12EB12CAC0EBD1EB4E26B2E712C1E +:100CD000C701B601A50111DE8823E1F18091660309 +:100CE0009091670321E08734920708F0A7C1C601FD +:100CF000B501EFDE882E882359F380916603909129 +:100D00006703869D8001879D100D969D100D11240F +:100D10000D531C4FC801B50146E150E00E94393E19 +:100D2000B8016A5E7F4FC6010E94882880916603E1 +:100D300090916703869DF001879DF00D969DF00DC3 +:100D40001124ED53FC4F83A2019690936703809387 +:100D50006603BECF2091660330916703C751DF4F12 +:100D600039832883C95ED040F70185A18250823043 +:100D7000A8F184E290E0C751DF4FE881F981C95EB4 +:100D8000D040E89F8001E99F100DF89F100D1124BD +:100D90000D531C4FC80160E071E046E150E00E9435 +:100DA000393EC801469660E071E04DE050E00E9497 +:100DB000393E82E0F80183A3C751DF4F2881398192 +:100DC000C95ED0402F5F3F4FC751DF4F3983288323 +:100DD000C95ED0403093670320936603A6EE2A2EA7 +:100DE000A3E03A2E80E090E07E010894E11CF11C23 +:100DF000F7E1CF2ED12CCC0EDD1EC751DF4FE8819D +:100E0000F981C95ED0408E179F0708F01EC1FC0112 +:100E10003196C351DF4FF983E883CD5ED040C7518F +:100E2000DF4F28813981C95ED040E217F30708F00F +:100E300026C1C1018397F101B496C151DF4FF983F7 +:100E4000E883CF5ED0405F01C351DF4F48805980B7 +:100E5000CD5ED040CA51DF4F8883C65ED04091013D +:100E60002D503040C551DF4F39832883CB5ED040B1 +:100E7000C951DF4F39822882C75ED040392EC70161 +:100E8000CA51DF4F6881C65ED040732D46E150E005 +:100E90000E94393E88240AC00E0D1F1DF801808172 +:100EA00090E00E94FD3DF80180838394F70101905A +:100EB0000020E9F73197EE19FF09082D10E00E1711 +:100EC0001F0750F3EDED8E2EEFEF9E2E8A0C9B1C2C +:100ED000682C292CC601B40146E150E00E94393E3D +:100EE00077240AC00C0D1D1DF801808190E00E943E +:100EF000FD3DF80180837394F60101900020E9F72D +:100F00003197EC19FD09072D10E00E171F0750F35C +:100F1000C701B60146E150E00E942B3E282F392F31 +:100F2000C951DF4FE881F981C75ED040808181508F +:100F3000823008F480C0F50180818150823008F44D +:100F400077C0121613060CF055C0CE018D96CA510B +:100F5000DF4F6881C65ED040732D46E150E00E94AD +:100F6000393ECA51DF4F8881C65ED040932D662D31 +:100F7000722D46E150E00E94393E862D922DBE0131 +:100F8000635D7F4F46E150E00E94393ECE018D9671 +:100F9000C551DF4F68817981CB5ED0404DE050E094 +:100FA0000E94393E84010A5E1F4FC551DF4F888180 +:100FB0009981CB5ED040B8014DE050E00E94393EAF +:100FC000C801BE01635D7F4F4DE050E00E94393E95 +:100FD000C951DF4FE881F981C75ED0408081F501BA +:100FE0009081C951DF4FE881F981C75ED04090837D +:100FF000F50180830894411C511C24E230E0A20ECC +:10100000B31EC751DF4F88819981C95ED040481611 +:10101000590608F434CFC151DF4F28803980CF5EA4 +:10102000D040C351DF4F88819981CD5ED040E5CE5D +:1010300028513C4F86CF285E33407DCFC751DF4FCC +:1010400099838883C95ED0408FCEC051DF4F0FB6E1 +:10105000F894DEBF0FBECDBFCF91DF911F910F91EE +:10106000FF90EF90DF90CF90BF90AF909F908F90C8 +:101070007F906F905F904F903F902F900895C101A7 +:101080008496C151DF4F99838883CF5ED040C3CF10 +:101090008F929F92AF92BF92CF92DF92EF92FF9288 +:1010A0000F931F93CF93DF9380916803909169030F +:1010B00020916A0330916B032817390728F4309385 +:1010C000690320936803C90104968217930730F4DB +:1010D00024503040309369032093680380E060E03F +:1010E0000E94372281E06FE70E942822C3E1D0E00E +:1010F00081E060E40E9428222197D1F783E091E00B +:101100000E942C23C3E1D0E081E060E40E94282209 +:101110002197D1F781E06FE70E9428222091660392 +:10112000309167032115310509F464C140916803CA +:1011300050916903CA0105964817590708F033C151 +:101140004217530708F02FC164E270E0469F700118 +:10115000479FF00C569FF00C112486EE93E0E80EAA +:10116000F91EEA0191E0C92ED12CBB24B3948091E1 +:101170006A0390916B03C817D90709F0BB24AC2C04 +:1011800080E06C2D0E94372204E510E007C060E08B +:1011900081E00E9428220150104049F0BB20B9F3A1 +:1011A0006FE781E00E94282201501040B9F781E0EA +:1011B0006A2D0E943722870103521040902E812E03 +:1011C000C8016B2D43E50E944322F70180818150C5 +:1011D000823008F4BDC0BB2009F0A4C0860121966E +:1011E0004091680350916903CA010596C817D90751 +:1011F000E0F120916603309167032630310508F055 +:1012000047C0EE24E39482E56E2D0E94372281E0F0 +:1012100060E00E94282281E060E00E942822E3949E +:101220007E2D763081F78091680390916903980153 +:10123000280F391F40916A0350916B0342175307DF +:1012400008F4E2C02150304030936B0320936A03CE +:101250000430110509F02CCF009709F429CF01972C +:10126000909369038093680323CF209166033091A4 +:1012700067030894C11CD11C64E270E0E60EF71EFF +:10128000C217D30708F471CF2630310508F4B9CF5F +:10129000E7E2F0E04E9FC0014F9F900D5E9F900DE2 +:1012A00011248D539F4FB9010E94A83D88E0E82E7C +:1012B000E60E83EC90E0B9010E94A83DCE2CC61A40 +:1012C000C8E0D0E0BB24B39482E56B2D0E943722A6 +:1012D00081E060E00E9428224C2F9E01295F3F4F51 +:1012E0002C173D070CF484C060E00AC0E41650F0EF +:1012F000669560684F5F842F90E0281739074CF09F +:101300004C15A0F766954F5F842F90E0281739079A +:10131000BCF781E00E942822B39428967B2D76307A +:1013200099F681CF82E893E0692D782D46E150E06F +:101330000E94393EB8016A5E7F4F8CE693E04DE033 +:1013400050E00E94393EF70180818093980346CF98 +:1013500089E46A2D0E943722BB2041F181E06FE7CA +:101360000E94282281E063E40E94282281E06DE54A +:101370000E94282281E06DE50E94282281E06DE52F +:101380000E94282281E06BE50E94282281E06BE523 +:101390000E94282281E063E40E9428226FE781E016 +:1013A0000E94282218CF00E010E027CF81E060E003 +:1013B0000E94282281E06CE30E94282281E062E200 +:1013C0000E94282281E062E20E94282281E062E2FB +:1013D0000E94282281E064E20E94282281E064E2E7 +:1013E0000E94282281E06CE30E94282260E0D7CF8F +:1013F00060E08FCF80E061E00E9437228FE091E0D3 +:1014000060E044E50E944322DF91CF911F910F914C +:10141000FF90EF90DF90CF90BF90AF909F908F9014 +:1014200008958130910559F0009721F48091EF35AE +:10143000882309F408958CEE95E30C94B22B109256 +:10144000EC351092EF350895DF92EF92FF920F93F3 +:101450001F93CF93DF93082F2B9882E282B95D9878 +:10146000429A289A45980E947B23CDEAD3E0FE0158 +:1014700001900020E9F73197EC1BFD0B8E2F819531 +:10148000880F865D65E00E943722CE0160E044E56A +:101490000E9443220E94F021002309F438C00AE68A +:1014A00014E0DD2480E06D2D0E9437222AE1E22E37 +:1014B00081E060E00E942822EA94D1F790E1E92ED1 +:1014C000F12CE00EF11EE801FE01649181E00E9422 +:1014D00028222196EC16FD06B9F7E8012F96015057 +:1014E0001040FE01649181E00E94282221970C1790 +:1014F0001D07B9F70AE181E060E00E94282201504F +:10150000D1F7D394FD2DF43051F18701CBCFC6E252 +:10151000D4E0FF2480E06F2D0E94372201E281E0B9 +:1015200060E00E9428220150D1F78E010F5E1F4F0C +:10153000FE01649181E00E94282221960C171D076C +:10154000B9F782E2E82E81E060E00E942822EA9466 +:10155000D1F7F394FF2DF43011F0E801DBCF98E0E0 +:101560002FEB37E249E0215030404040E1F700C026 +:10157000000085B1892785B9F3CFEF920F9336B17B +:1015800091E0811190E0331F3327331F931759F0F7 +:10159000E9B1E095E170F0E081E090E0662339F494 +:1015A000E817F90749F080E00F91EF90089580E087 +:1015B00090E0E817F907B9F766B16095617070E0DF +:1015C00081E090E0442311F080E090E06817790713 +:1015D00051F790B181E0211180E0991F9927991F5F +:1015E000891709F326B191E0011190E081E021FF14 +:1015F00080E09817C1F229B191E0E11090E081E01C +:1016000023FF80E08927D0CF559A209A3A9A3D9AB5 +:101610003E9A3B9A239A289A429A45984698439A2A +:101620002B9A8FE781B95C9A599A5A9A5F9A5B9A7A +:10163000179A589A409A419AE3E7F0E080818160D6 +:101640008083EDE6F0E0808182608083808181602C +:10165000808308951F93DF93CF93CDB7DEB72A978A +:101660000FB6F894DEBF0FBECDBFCE010196DC01F0 +:10167000ECE2F3E02AE001900D922150E1F7E091D5 +:101680009A03F0E0F595E795F595E795F595E795DB +:10169000F595E7951FB7F894E53008F0E4E0F0E041 +:1016A000EE0FFF1FE80FF91F20813181220F331F3A +:1016B00040E050E060E07DE281E391E00E94DE3DA9 +:1016C0003093A9032093A8031FBF82E086BB2A960C +:1016D0000FB6F894DEBF0FBECDBFCF91DF911F9143 +:1016E00008951F920F920FB60F920BB60F9211240E +:1016F0002F933F934F935F936F937F938F939F931A +:10170000AF93BF93CF93DF93EF93FF93489B2FC08B +:10171000E0919A038091A303882309F03DC0F0E093 +:10172000E45DFE4F249130E0220F331F2115310577 +:10173000A9F537995DC080919A038F5F80939A03D2 +:1017400080919A03882309F064C04598429A489989 +:10175000FECF4298459A7EDFC091E235D091E335C5 +:10176000C330D10508F057C081E080939F03FF91FB +:10177000EF91DF91CF91BF91AF919F918F917F9129 +:101780006F915F914F913F912F910F900BBE0F90F2 +:101790000FBE0F901F90189524E230E080E090E09B +:1017A00040E050E068E18A539A4CFC01808180FF60 +:1017B00003C0683159F1542F4F5F842F90E0821796 +:1017C00093070CF1561708F4B4CF862FE82FF0E0FA +:1017D000EA53FA4C908191FF03C09081916090830D +:1017E0009081946090838F5F581780F7379BA3CFC9 +:1017F00080919A03882309F4A3CF80919A038150A2 +:1018000080939A039DCF4831E9F2CDCF542F642FB6 +:10181000D3CF459A9BCF8DEA93E061E371E046E137 +:1018200050E00E94393EC851DC4FD093C535C0937B +:10183000C43510929E0381E080939F038093A003A0 +:101840001092E3351092E2358FCF1F920F920FB6B0 +:101850000F920BB60F9211241F932F933F934F9328 +:101860005F936F937F938F939F93AF93BF93CF9328 +:10187000DF93EF93FF9386B190E095958795817004 +:1018800090919C03891791F09091A603923009F4EE +:101890006DC010929C0311E010939F03C091E2353C +:1018A000D091E335C330D10508F047C086B18170CF +:1018B00011E0812790919E038917C9F080939E03C0 +:1018C00080919E03882349F546988FE781B98091DE +:1018D0006B008F7780936B00C091E235D091E33538 +:1018E000C330D10508F045C081E080939F03FF918C +:1018F000EF91DF91CF91BF91AF919F918F917F91A8 +:101900006F915F914F913F912F911F910F900BBE5F +:101910000F900FBE0F901F90189511B8469A8091A6 +:101920006B00806880936B0080B180788093E13594 +:101930001092E3351092E235D7CF8DEA93E061E360 +:1019400071E046E150E00E94393EC053D84FD09339 +:10195000C535C093C43510929E0310939F03109316 +:10196000A0031092E3351092E235A0CF80939C0340 +:1019700092CF8DEA93E061E371E046E150E00E948E +:10198000393EC854D44FD093C535C093C435109256 +:101990009E0310939F031093A0031092E3351092BF +:1019A000E235A2CF1F93E0B1E0688091E2359091DB +:1019B000E3358430910588F48330910509F487C0BC +:1019C000DC01A35EBC4F2C912E1709F404C11092C8 +:1019D000E3351092E2351F910895F0E0EA5DFE4F85 +:1019E000E49132E08F3B930748F59C0123703070FF +:1019F0002230310509F4BBC02330310509F449C157 +:101A00002130310509F418C1EE0FEE0FE093E435F3 +:101A10004091E83550E09A01220F232F221F330B0B +:101A20002093E935440F551F422B4093E83501962A +:101A30009093E3358093E2351F910895F2E08F3B58 +:101A40009F0709F4C1C022E0803C920709F4CEC090 +:101A500032E0813C930709F4E2C1F2E0823C9F0747 +:101A600009F0B5CF8091E435982F990F990F909395 +:101A7000E435E82B9091E835E917C9F08DEA93E059 +:101A800062E971E046E150E00E94393E80E490E076 +:101A90009093C5358093C43510929E0381E0809366 +:101AA0009F038093A0031092E3351092E235E091FA +:101AB000E535F0E0EA53FA4C8081826080838081D2 +:101AC0008160808380818B7F80832B9A80CFF0E040 +:101AD000EA5DFE4F1491E0919A038091A30388235D +:101AE00009F082C0F0E0E45DFE4FE4911E1708F0BB +:101AF0004DC1E0919A03882309F074C0F0E0E45DE1 +:101B0000FE4FE49180919C03E89F802D1124810F6A +:101B10008093E53590E0DC01AA53BA4C2C9122FD6C +:101B2000E0C0982F8827990F8D539C4F9093EB35E9 +:101B30008093EA358C9184608C938C918D7F8C930B +:101B400080919A038093DE3580919C038093DF35EA +:101B50001093E0352B981092E8351092E7351092EB +:101B6000E6358091E2359091E335019661CF509151 +:101B7000E435452F407C4E2B2091E63542278431B9 +:101B8000910578F0E091EA35F091EB354193F093CF +:101B9000EB35E093EA355091E4358091E235909150 +:101BA000E3356091E9352091E73530E0260F311DAE +:101BB000240F311D2093E7353093E935550F550F2C +:101BC0005093E435019634CFEE0FEE0FE093E435F9 +:101BD00080EC92E02DCF2091A203222309F0F7CED2 +:101BE000019626CFE2E18ECFE2E180CF8091E4350D +:101BF000982F990F990F9093E435807C8E2B9091BC +:101C0000E635891709F46AC08DEA93E06CE671E065 +:101C100046E150E00E94393E8EE390E09093C53556 +:101C20008093C43510929E0381E080939F0380933C +:101C3000A00381E090E0FCCE5091E435452F407C3C +:101C40004E2B2091E83542278431910578F0E091C0 +:101C5000EA35F091EB354193F093EB35E093EA35BB +:101C60005091E4358091E2359091E3356091E9350A +:101C70002091E63530E0260F311D240F311D2093D1 +:101C8000E6353093E935550F550F5093E4350196FD +:101C9000CFCE4091E4354E2B2091E7354227843159 +:101CA000910568F0E091EA35F091EB354193F093BE +:101CB000EB35E093EA358091E2359091E335509130 +:101CC000E9352091E83530E0250F311D240F311D15 +:101CD0002093E8353093E9350196AACE81EC92E065 +:101CE000A7CE30919A0320919C038DB79EB70C9795 +:101CF0000FB6F8949EBF0FBE8DBFADB7BEB711969D +:101D00008DEA93E0EDB7FEB79283818386E190E0A0 +:101D100013969C938E93129788E591E015969C9369 +:101D20008E93149716963C93169717961C921797B6 +:101D300018962C93189719961C9219971A961C931B +:101D40001A971B961C920E94483E8DE390E0909358 +:101D5000C5358093C43510929E0381E080939F0324 +:101D60008093A0031092E3351092E2358091E5351F +:101D700090E02DB73EB7245F3F4F0FB6F8943EBFBB +:101D80000FBE2DBFDC01AA53BA4CCBCE20919A03D3 +:101D90008DB79EB70A970FB6F8949EBF0FBE8DBF42 +:101DA000ADB7BEB711968DEA93E0EDB7FEB792835B +:101DB000818386E190E013969C938E93129782E440 +:101DC00091E015969C938E93149716961C931697F4 +:101DD00017961C92179718962C93189719961C9281 +:101DE0000E94483E8CE390E09093C5358093C435C3 +:101DF00010929E0381E080939F038093A003109232 +:101E0000E3351092E2358091A3032DB73EB7265FEC +:101E10003F4F0FB6F8943EBF0FBE2DBF6ACE8091E4 +:101E2000E435982F990F990F9093E435807C8E2B91 +:101E30009091E735891759F08DEA93E06FE771E0EB +:101E400046E150E00E94393E8FE390E0E7CE82EC1D +:101E500092E0EECD4091A4035091A503E2EEF2E0B2 +:101E60002591349160E07FEF2627372791EA692F8B +:101E7000632770E0660F771F6A5D7D4FFB016591F8 +:101E80007491322F2227262737279327E92FF0E056 +:101E9000EE0FFF1FEA5DFD4F65917491322F2227EF +:101EA00026273727EBEFE327F0E0EE0FFF1FEA5D71 +:101EB000FD4F65917491322F222726273727B82F9F +:101EC000BB0FA0E0AD53BC4F80E090E0722F6627BF +:101ED000ED91E327F0E0EE0FFF1FEA5DFD4F259146 +:101EE000349126273727019662E08030960771F7F4 +:101EF0003093A5032093A40342175307C9F08DEA3A +:101F000093E065EA71E046E150E00E94393E86E4E4 +:101F100090E09093C5358093C43510929E0381E084 +:101F200080939F038093A0031092E3351092E235D3 +:101F300008951F920F920FB60F920BB60F921124B5 +:101F40002F933F934F935F936F937F938F939F93C1 +:101F5000AF93BF93EF93FF9390B180919E0388233B +:101F600009F456C0892F80789091E135891709F4DA +:101F70004FC08093E1359091A303992309F46FC07A +:101F8000882309F461C020B12F708091E435282B9B +:101F90002093E4358091E2359091E33582309105CC +:101FA00009F45FC0009709F446C08130910509F437 +:101FB0006DC032E08330930708F458C0A2E083304C +:101FC0009A0709F49AC0B2E084309B0709F530E023 +:101FD0008091A4039091A503822B932B9093A5034A +:101FE0008093A4038091E53535DFE091E535F0E09D +:101FF000EA53FA4C80818260808380818160808393 +:1020000080818B7F80832B9A1092E3351092E2358A +:10201000FF91EF91BF91AF919F918F917F916F91C0 +:102020005F914F913F912F910F900BBE0F900FBE7C +:102030000F901F901895213A59F781E090E0909306 +:10204000E3358093E235E4CF80B190E082959295BC +:10205000907F9827807F98278093E435D9CFA2DCA2 +:10206000D7CF2B3FE9F0213A79F6D2CF3091E53541 +:10207000F32FFF0FE0E0E80FF91FE054FC4F20833F +:1020800001969093E3358093E235C2CF213A09F06F +:10209000BBCF82E090E09093E3358093E235B8CFF8 +:1020A00083E090E09093E3358093E2352091A7039D +:1020B0002093E535822F90E0FC01EA53FA4C308101 +:1020C00032FD26C0982F8827990F8D539C4F9093EF +:1020D000EB358093EA3580818460808380818D7FB9 +:1020E000808380919A038093DE3580919C03809356 +:1020F000DF352093E0352B988BCF1092A4032093EB +:10210000A50384E092E09093E3358093E23580CF9D +:1021100050919A0340919C032DB73EB72C5030400C +:102120000FB6F8943EBF0FBE2DBFEDB7FEB7319688 +:102130002DEA33E0ADB7BEB712963C932E931197BC +:1021400026E130E03383228328E531E035832483A0 +:102150005683178240871186938782870E94483E64 +:1021600087E490E09093C5358093C43510929E0328 +:1021700081E080939F038093A0031092E335109237 +:10218000E2352DB73EB7245F3F4F0FB6F8943EBF00 +:102190000FBE2DBF3DCFF89490919E03992341F43B +:1021A0008F7782B9459A079BFECF0799FECF459856 +:1021B000789408958AE082B9459A079BFECF0799E3 +:1021C000FECF4598E091A50381EAE827F0E0EE0F05 +:1021D000FF1FEA5DFD4F859194913091A40320E0AB +:1021E000822793279093A5038093A40381E182B96A +:1021F000459A079BFECF0799FECF45980895982FE3 +:1022000092959F7092B9459A079BFECF0799FECF92 +:102210004598482F4F70E091A503E827F0E0EE0FB6 +:10222000FF1FEA5DFD4F859194913091A40320E05A +:10223000822793279093A5038093A40342B9459ADC +:10224000079BFECF0799FECF459808952F923F92A6 +:102250004F925F926F927F928F929F92AF92BF92B6 +:10226000CF92DF92EF92FF920F931F93DF93CF9362 +:1022700000D00F92CDB7DEB78983692EA0E2CA2EB7 +:10228000A3E0DA2E992422243324EE24FF2400E054 +:1022900010E088C01070C801880F991F2801440CF5 +:1022A000452C441C55085194482A592AF60101919D +:1022B000852D9927820D931D800F911DAFEF4A2226 +:1022C0005524D6011196AC906F010894C11CD11C05 +:1022D000A7014A0D511D9C0120703170232F332717 +:1022E000420F531F3FEF232E312C282239227180B9 +:1022F0002FEFE22EF12CE422F522872C8E240425E8 +:1023000010E0A224BB24F501E07CF070F595E79580 +:10231000F595E795F595E795F595E7959801207C76 +:1023200030703595279535952795E22BF32B882D21 +:10233000829586958695837090E0E82BF92BE4587A +:10234000FE4F84914A835B8326DF0F73107004581D +:102350001E4FF80184911FDF80919F034A815B81AA +:10236000882309F0A9C00894C11CD11C8201070D63 +:10237000111D40705170452F5527040F151FF50191 +:10238000EF73F070E458FE4F849105DFE82DF0E024 +:10239000EF73F070E458FE4F8491FDDE9394F92DB5 +:1023A000FE3A41F0292D243009F074CF9981C92ECD +:1023B000D62C70CF1070C801880F991F5801AA0C35 +:1023C000AB2CAA1CBB08B194A82AB92AD6010C913F +:1023D000200E311C8B2D9927280E391E1196CC907A +:1023E000EC0CF11CC10180709170892F9927E80EC7 +:1023F000F91E0A2510E0C224DD24F601E07CF0700D +:10240000F595E795F595E795F595E795F595E795B4 +:10241000C801807C90709595879595958795E82B58 +:10242000F92BE458FE4F8491B6DEF801EF73F0709B +:10243000E458FE4F8491AFDEF601EF73F070E4587C +:10244000FE4F8491A8DEF101E07CF070F695E795EF +:10245000F695E795C501807C90700024880F991F40 +:10246000001C880F991F001C892F902DE82BF92B39 +:10247000C701807C9070929582958F7089279F709C +:102480008927E82BF92BE458FE4F849184DEF10173 +:10249000EF73F070E458FE4F84917DDEF701EF7327 +:1024A000F070E458FE4F849176DEF501EF73F07022 +:1024B000E458FE4F84916FDE0F900F900F90CF91F4 +:1024C000DF911F910F91FF90EF90DF90CF90BF9021 +:1024D000AF909F908F907F906F905F904F903F90C4 +:1024E0002F9008951F93CF93DF938FEF99E6A8E184 +:1024F00081509040A040E1F700C000008CEE95E3D1 +:1025000063EB71E041E00E94B32E882309F46DC0B3 +:102510008CEE95E363EC73E040E052E00E944829C2 +:1025200097FD78C010920836109207368BE796E137 +:102530000E94483D1FB7F8940E94F23CEC011FBF77 +:102540008CEE95E30E94B22B0E946F23209761F1DD +:10255000ADB7BEB718970FB6F894BEBF0FBEADBFEC +:10256000EDB7FEB731968DEA93E012969C938E9369 +:10257000119786E190E09383828380ED91E09583CB +:102580008483D783C6830E94483E8DB79EB7089642 +:102590000FB6F8949EBF0FBE8DBF81E00E94240A43 +:1025A000DF91CF911F91089589E062E00E94372268 +:1025B0008DEA93E060EC71E046E150E00E94393E24 +:1025C0008DEA93E060E044E50E9443228FEF9AE1B8 +:1025D000A7EB81509040A040E1F700C00000FE0151 +:1025E0000995DF91CF911F91089564E00E943722F1 +:1025F0008BE696E060E00E94C4228DEA93E06EE5EF +:1026000076E00E94053E80E00E94240ADF91CF918F +:102610001F9108958DEA93E06EE476E00E94053EF6 +:1026200081E00E94240A7ECFCF93DF930E946F2324 +:1026300080E060E00E94372288E396E061E00E943B +:10264000C42286E296E00E940C3E8195880F865D4A +:1026500062E00E94372286E296E060E00E94C42297 +:102660004DB75EB7485050400FB6F8945EBF0FBEEE +:102670004DBFEDB7FEB73196CDEAD3E0ADB7BEB7EB +:102680001296DC93CE93119786E190E09383828338 +:1026900082EE91E0958384838091AC0386831782D8 +:1026A0000E94483EFE0101900020E9F73197EC1BA3 +:1026B000FD0B4DB75EB7485F5F4F0FB6F8945EBF36 +:1026C0000FBE4DBF8E2F8195880F865D63E00E94FF +:1026D0003722CE0160E044E50E9443220E94F021AF +:1026E00093E028E04FEF53ED60E3415050406040ED +:1026F000E1F700C0000085B1822785B9915091F7BC +:102700000E94F421DF91CF910895CF92DF92EF9252 +:10271000FF920F931F93DF93CF9300D000D0CDB7DC +:10272000DEB780E060E00E9437220E946F2380E0E5 +:1027300060E00E94372282E196E060E00E94C422BD +:1027400080E062E00E9437228FEF95E060E00E9417 +:10275000C42280E063E00E94372289EF95E060E0C8 +:102760000E94C422499BFECF4A9BFCCF4C9BFACFD0 +:1027700080E060E00E9437220E946F2380E062E0E8 +:102780000E9437228BEE95E060E00E94C42280E038 +:1027900063E00E9437228EED95E060E00E94C42243 +:1027A00080E064E00E94372281ED95E060E00E94C5 +:1027B000C4228E010F5F1F4F83EFE82E81E0F82EB9 +:1027C000B4E0CB2ED12C16C0809115368F3F29F066 +:1027D000809115368F5F8093153680E061E20E940C +:1027E00028226091153680E00E94282280E060E275 +:1027F0000E94282280E060E00E94372286EC95E06B +:1028000060E00E94C422809115362DB73EB7285053 +:1028100030400FB6F8943EBF0FBE2DBFEDB7FEB7E8 +:102820003196ADB7BEB712961C930E931197D38213 +:10283000C282F582E482868317820E94483E2DB7C9 +:102840003EB7285F3F4F0FB6F8943EBF0FBE2DBF77 +:10285000C80160E044E50E9443228FEF99E6A8E1B9 +:1028600081509040A040E1F700C00000499B04C0A7 +:102870004A9B02C04C99FACF4A9BA6CF49990BC0FC +:1028800080911536813808F4A8CF80911536815093 +:1028900080931536A2CF4C99A0CF6091153681E078 +:1028A00090E00E9490408FEF99E6A8E1815090401F +:1028B000A040E1F700C000000E946F230F900F902E +:1028C0000F900F90CF91DF911F910F91FF90EF909C +:1028D000DF90CF90089580E060E00E9437220E9450 +:1028E0006F2380E060E00E94372280EB95E061E09A +:1028F0000E94C42289E062E00E94372280EA95E0CB +:1029000060E00E94C42289E063E00E94372280E9EF +:1029100095E060E00E94C4228FE065E00E943722CB +:1029200084E895E060E00E94C422DCCD1F930E9401 +:102930006F2380E060E00E94372282E893E060E04D +:1029400044E50E94432280E061E00E9437228CEE41 +:1029500095E36CE673E043E00E94B32E882309F40C +:102960008AC080919803833029F1863019F182E082 +:102970008093A6038CEE95E369E076E34DE056E3A1 +:102980000E94D5278823D1F48BE595E060E00E9472 +:10299000C4228FEF93E2A4EF81509040A040E1F772 +:1029A00000C0000010E08CEE95E30E94B22B812F56 +:1029B0001F91089581E08093A603DCCF80E061E061 +:1029C0000E94372280919803853009F4BFC0863079 +:1029D00008F05FC0833009F4A1C0843039F48DE37E +:1029E00095E060E00E94C4228091980391E08630D7 +:1029F00008F490E09093C3354F998CC0992309F463 +:102A00005CC081E08093A20348E754E060E070E09E +:102A10008CEE95E30E94CA2A8CEE95E363EC73E09A +:102A200040E052E00E944829E091C303F0E0EC53FB +:102A3000FC4F10821092D90380E062E00E9437229E +:102A400084EC93E060E044E50E94432280E064E08F +:102A50000E94372282EE94E060E00E94C4228091BE +:102A6000A203882379F511E08CEE95E30E94B22B46 +:102A7000812F1F9108958CEE95E36CE673E041E0A1 +:102A80000E94B32E882309F464C081E08093A203DE +:102A900071CF873009F452C0873008F447C08830BE +:102AA00009F0A4CF80EF94E060E00E94C42281E0AE +:102AB0008093A3038091980399CF44E254E060E0AF +:102AC00070E0A6CF8DE460E00E94372281E060E0F4 +:102AD0000E94282281E068E70E94282281E06EE7B8 +:102AE0000E94282281E069E70E94282281E069E7AC +:102AF0000E94282281E06EE70E94282281E068E798 +:102B00000E94282211E08CEE95E30E94B22B812FC7 +:102B10001F91089581E08093A20370CF8CE495E02B +:102B200060E00E94C4228091980360CF89E195E023 +:102B300060E00E94C4228091980358CF85E095E020 +:102B400060E00E94C4228091980350CF8DE295E00E +:102B5000ABCF80E795E060E00E94C4221ACF2898AE +:102B60008FE798E3A1E081509040A040E1F700C0DA +:102B7000000082E282B95D98289A0C947B231F930F +:102B80001FB7F894E0919A03F0E0EE0FFF1FE850B2 +:102B9000F041808180939A030E94040B10929A0363 +:102BA00010929B0310929F0310929C0310929D031E +:102BB00010929E031092A10382E08093A6031092CC +:102BC000A7031092A2031092A3031092A0031092E5 +:102BD000AB031092AA031092C5351092C43510921F +:102BE000E3351092E23580E090E0FC01EA53FA4CC4 +:102BF0001082019688319105C1F711B8469A28983C +:102C00008FE798E3A1E081509040A040E1F700C039 +:102C1000000080B18F778093AC0346988FE781B92D +:102C2000289A9DDF0E946F231FBF1F910895FF9276 +:102C30000F931F93CF93DF938C01F090A003C0916B +:102C4000C435D091C5359BDF0E946F2380E060E0E2 +:102C50000E943722FF2009F43FC082E597E061E03F +:102C60000E94C42280E061E00E943722C80160E037 +:102C700044E50E9443228DB79EB708970FB6F8949B +:102C80009EBF0FBE8DBFEDB7FEB731960DEA13E0C4 +:102C9000ADB7BEB712961C930E93119786E190E0E4 +:102CA0009383828386EF91E095838483D783C68361 +:102CB0000E94483E8DB79EB708960FB6F8949EBF07 +:102CC0000FBE8DBF80E065E00E943722C80160E042 +:102CD00044E50E944322FFCF8CE397E061E00E942D +:102CE000C42280E061E00E943722C80160E044E530 +:102CF0000E944322F0CF209107363091083682E0BF +:102D00002030380759F0F901ED53FC4F80812F5FD7 +:102D10003F4F309308362093073608958CEE95E3A5 +:102D200063EC73E040E052E00E94482997FD0BC03D +:102D3000109208361092073685B198E0892785B938 +:102D400020E030E0E0CF89EF91E071DFF1CF9F929A +:102D5000AF92BF92CF92DF92EF92FF920F931F93A9 +:102D6000CF93DF9387E893E10197F1F700C000006C +:102D700029E0E0E0F0E0209357006491A7E8B3E198 +:102D80001197F1F700C00000E3E0F0E02093570056 +:102D9000849190E0E7E8F3E13197F1F700C000009B +:102DA000E2E0F0E020935700249130E0A7E8B3E19F +:102DB0001197F1F700C000008A3D910509F418C28F +:102DC000EDB7FEB73C970FB6F894FEBF0FBEEDBF50 +:102DD00031967DEAC72E73E0D72EADB7BEB71296F7 +:102DE000DC92CE92119746E150E05383428349E052 +:102DF00052E05583448366831782918780873387A7 +:102E000022870E94483EEDB7FEB73C960FB6F89475 +:102E1000FEBF0FBEEDBF81E00E94240A2091AC03EB +:102E20002F3709F4F2C12D3049F14DB75EB7485044 +:102E300050400FB6F8945EBF0FBE4DBFEDB7FEB762 +:102E40003196ADB7BEB71296DC92CE92119786E15D +:102E500090E09383828380E392E09583848326834A +:102E600017820E94483EEDB7FEB738960FB6F89429 +:102E7000FEBF0FBEEDBF81E00E94240A10928000C9 +:102E8000109281008091640088608093640028988B +:102E900012B842985D98459881E061E041E021E0F8 +:102EA00000E0EE240E94BD0A882309F420C211E04C +:102EB00012B980E061E041E021E000E0EE240E94F0 +:102EC000BD0A8127C82FD0E012B8429A81E061E0A4 +:102ED00041E021E00E94BD0AF82E12B981E061E0D4 +:102EE00041E021E00E94BD0AF1262F2D30E02C2B7D +:102EF0003D2B1827122B09F0F0C112B8429852E06E +:102F0000F52EF2B8A12EBB2481E060E041E021E083 +:102F100000E0EE240E94BD0A982E12B85D9A81E06E +:102F200061E041E021E00E94BD0A11E09126C92D37 +:102F3000D0E0812790E0C82BD92BF2B881E061E086 +:102F400041E021E00E94BD0ACA29DB2918271C2B79 +:102F500009F0B9C112B85D9844E0F42EF2B8A12E80 +:102F6000BB2481E061E040E021E000E0EE240E942B +:102F7000BD0A982E12B8459A81E061E041E021E057 +:102F80000E94BD0A11E09126C92DD0E0812790E072 +:102F9000C82BD92BF2B881E061E041E021E00E942A +:102FA000BD0ACA29DB2918271C2B09F082C112B8D7 +:102FB000459880E282B9A12EBB2481E061E041E026 +:102FC00020E000E0EE240E94BD0AF82E88E082B9DD +:102FD00081E061E041E021E00E94BD0A11E0F126BC +:102FE000CF2DD0E0812790E0C82BD92B88E282B981 +:102FF00081E061E041E021E00E94BD0ACA29DB29AD +:1030000018271C2B09F04BC112B880E182B981E06E +:1030100061E041E021E001E0EE240E94BD0AFF24CE +:10302000F394F826F12A09F030C112B880E482B98D +:1030300081E061E041E021E000E0EE24E3940E94C1 +:10304000BD0A91E09827892F90E02F2D30E0822B48 +:10305000932B009709F00FC112B8289A90DD489978 +:1030600000C1459A11B8469A8FEF9FEF03C00197B0 +:1030700009F447C1079BFBCF8FEF9FEF03C0019778 +:1030800009F449C10799FBCF459846988FE781B964 +:1030900081E060E041E020E000E0EE240E94BD0A13 +:1030A000882309F4D4C00AE614E0AA2480E06A2D3B +:1030B0000E9437223AE1F32E81E060E00E9428224C +:1030C000FA94D1F7F02EE12EC0E0D0E00DC0C70198 +:1030D000E92FFE2DEC0FFD1F649181E00E94282254 +:1030E0002196C031D10531F09A2D923081F7EAEA6C +:1030F000F4E0F0CFCFE0D0E00EC0C701E92FFE2D05 +:10310000EC0FFD1F649181E00E9428222197BFEF00 +:10311000CF3FDB0731F0AA2DA23079F7EAEAF4E0DD +:10312000EFCF2AE1F22E81E060E00E942822FA949B +:10313000D1F7A394005F1F4FEA2DE43009F0B6CF1A +:1031400000D000D000D0EDB7FEB73196ADB7BEB716 +:103150001296DC92CE92119786E190E0938382835F +:1031600080E492E0958384830E94483EF6010190BA +:103170000020E9F73197ED5AF3402DB73EB72A5FAB +:103180003F4F0FB6F8943EBF0FBE2DBF8E2F8195D7 +:10319000880F865D65E00E943722C60160E044E545 +:1031A0000E9443222B988FEF93EDA0E38150904033 +:1031B000A040E1F700C0000085B198E0892785B9FB +:1031C0002FEF33ED40E3215030404040E1F700C0A5 +:1031D000000085B1892785B9DF91CF911F910F91AB +:1031E000FF90EF90DF90CF90BF90AF909F900895A9 +:1031F0002C3F310509F0E4CDEDEACE2EE3E0DE2EE2 +:103200002091AC032F3709F00ECE00D000D000D0B3 +:10321000EDB7FEB73196ADB7BEB71296DC92CE923F +:10322000119786E190E09383828382E292E0958316 +:1032300084830E94483EEDB7FEB736960FB6F894E9 +:10324000FEBF0FBEEDBF80E00E94240A17CE8DEABC +:1032500093E06AE776E00E94053E81E00E94240A3E +:1032600022CF8DEA93E061EB76E00E94053E81E09B +:103270000E94240AF6CE8DEA93E061EC76E00E948B +:10328000053E81E00E94240AE7CE8DEA93E061EDDD +:1032900076E00E94053E81E00E94240AC6CE8DEAB7 +:1032A00093E065EE76E00E94053E81E00E94240AEC +:1032B000ABCE8DEA93E066EF76E00E94053E81E0BA +:1032C0000E94240A74CE8DEA93E065E077E00E94C4 +:1032D000053E81E00E94240A3DCE8DEA93E068E13C +:1032E00077E00E94053E81E00E94240A06CE8DEA26 +:1032F00093E06BE277E00E94053E81E00E94240AA1 +:10330000D6CD8DEA93E060EA76E00E94053E81E04A +:103310000E94240AB1CE8DEA93E06FE876E00E9425 +:10332000053E81E00E94240AAFCEE4E6F0E0808111 +:10333000877F808383E48093800089E1809381008C +:103340000C942A0B9091A3039923E1F4E82FF0E069 +:10335000E45DFE4FE491F0E0262F30E02E173F07AA +:10336000B4F4AF014F5F5F4F55954795E0FD14C032 +:1033700031972E173F0759F06417B0F0862F8F5FF3 +:10338000841B0895262F30E02131310514F080E0B0 +:103390000895862F8F5F0895E42FF0E031972E1760 +:1033A0003F0751F780E00895842F860F0895FF921C +:1033B0000F931F938C01F22E0E94D424882379F15D +:1033C000C80163EC73E30E942C24882391F1E7E1A8 +:1033D000F4E3BF2DBB0FA0E0AD53BC4F81918D93A3 +:1033E00085E3E33CF807D1F7C80163EC73E30E947F +:1033F0002C24882311F1E3ECF3E3BF2DBB0FA0E0F5 +:10340000A159BA4F81918D9384E3E731F807D1F741 +:10341000C8010E94BC241F910F91FF9008958DE474 +:1034200092E005DCC80163EC73E30E942C2488233E +:1034300071F681E692E0FBDBCACF81E692E0F7DB32 +:10344000DACF2F923F924F925F927F928F929F920C +:10345000AF92BF92CF92DF92EF92FF920F931F93A2 +:10346000DF93CF93CDB7DEB760970FB6F894DEBF8A +:103470000FBECDBF982E792E862E8091A303882370 +:1034800009F4B7C004E210E0F2E14F2E512C80E0C5 +:1034900090E020E0FF24E8E1EE2E76E1A72EB12CAB +:1034A00061E7C62E62E0D62E1801122F8A539A4C7D +:1034B000DC018C9180FF35C08091DE35881661F18A +:1034C0008091DE352DB73EB72A5030400FB6F894C4 +:1034D0003EBF0FBE2DBFEDB7FEB731962DEA33E0EC +:1034E000ADB7BEB712963C932E931197B382A282CA +:1034F000D582C48286821782808711860E94483EC8 +:103500004DB75EB7465F5F4F0FB6F8945EBF0FBE14 +:103510004DBF8DEA93E08BDB5E2D583109F466C018 +:10352000F12E1F5F812F90E0821593050CF45AC095 +:10353000BE2DB83109F43EC08091A203882361F406 +:1035400066C0EE2DF0E0EA53FA4C80818E7F8083D6 +:1035500080818B7F8083E394FE1498F7EDB7FEB7EC +:1035600038970FB6F894FEBF0FBEEDBF31960DEA47 +:1035700013E0ADB7BEB712961C930E93119786E178 +:1035800090E09383828386E892E0958384838682A9 +:1035900017820E94483EEDB7FEB738960FB6F894F2 +:1035A000FEBF0FBEEDBF80E065E061D7C80160E0FF +:1035B00044E569D760960FB6F894DEBF0FBECDBF65 +:1035C000CF91DF911F910F91FF90EF90DF90CF90FF +:1035D000BF90AF909F908F907F905F904F903F9063 +:1035E0002F900895183109F4A3CF60CFF12EE12E6A +:1035F00098CFE62FF0E0E45DFE4FE4914E2E552487 +:103600008201000F111F01151105A1F240CFE8D66C +:1036100013D76B877C878D879E87FE1408F461C162 +:10362000482D50E05A8749871A01220C331CC101EA +:10363000880F991F880F991F880F991F820D931D5E +:103640009C0140E050E029833A834B835C830E2D3C +:10365000F101E457FF4F859194919C0140E050E0C7 +:103660002D833E834F8358871E2DAF2C42C0809000 +:10367000DF352091A60330E040E050E069817A8197 +:103680008B819C810E94893D6B017C018091093670 +:1036900090910A36A0910B36B0910C36C80ED91E07 +:1036A000EA1EFB1E282D30E0429EC001439E900D75 +:1036B000529E900D1124AA2797FDA095BA2FC80EEF +:1036C000D91EEA1EFB1EC00ED11CE11CF11C2F8569 +:1036D0003889322F2227330F2D533C4F892D972DB8 +:1036E000B701A6010E94F424882371F10F5FA01690 +:1036F00088F1402F50E0588B4F87FA01EA53FA4C7B +:10370000808180FDF3CF8091A303882309F0AFCFA0 +:10371000C0900936D0900A36E0900B36F0900C3607 +:10372000C00ED11CE11CF11C2091A60330E040E04A +:1037300050E06D817E818F8198850E94893DC60E03 +:10374000D71EE81EF91EC3CF8BE992E070DA0F5F37 +:10375000A01678F6E12EFA2C8091A303882309F0B5 +:103760004FC0F101E457FF4F65917491A090093665 +:10377000B0900A36C0900B36D0900C36AE0CB11C0F +:10378000C11CD11C80E090E02091A60330E040E015 +:1037900050E00E94893DA60EB71EC81ED91E0F2DEF +:1037A00010E00F5F1F4F0E191109222717FD2095FA +:1037B000322F892D972DB601A5010E948F268823CF +:1037C00059F487C0F801EA53FA4C80818E7F8083D8 +:1037D00080818B7F8083E394FE14D0F10E2D10E066 +:1037E000B801762F6627770F6D537C4F892D972D63 +:1037F0000E941D26882331F78EEB92E018DAE2CF83 +:103800008091DF3590E0489E5001499EB00C589E53 +:10381000B00C1124CC24B7FCC094DC2C8091093668 +:1038200090910A36A0910B36B0910C36A80EB91EB5 +:10383000CA1EDB1EAE0CB11CC11CD11CB101660F2F +:10384000771F660F771F660F771F620D731D9ACF64 +:10385000892D972D0E94D026882309F43EC089E146 +:103860008093AB03C1D5E8D5ADB7BEB71C970FB6F3 +:10387000F894BEBF0FBEADBFEDB7FEB731960DEAEF +:1038800013E012961C930E93119726E130E03383D8 +:1038900022832FED32E03583248329853A853783CF +:1038A00026832B853C854D855E85621B730B840BBF +:1038B000950B60877187828793870E94483E4DB73A +:1038C0005EB7445F5F4F0FB6F8945EBF0FBE4DBF4B +:1038D0006ACE8BEA92E0ABD97FCF8DEC92E0A7D98C +:1038E000BECF282D30E03A8729871901220C331CDE +:1038F00033CF2F923F924F925F926F927F928F922F +:103900009F92AF92BF92CF92DF92EF92FF920F936E +:103910001F93DF93CF93CDB7DEB7CD54D0400FB612 +:10392000F894DEBF0FBECDBF55D529D9499B04C041 +:103930004A9902C04C9B07C0499904C04A9902C0E9 +:103940004C9901C004DAF1DC0E941413C8D67894B3 +:103950008FE79AE1A6E081509040A040E1F700C0D7 +:1039600000003ED58FE79AE1A6E081509040A0404C +:10397000E1F700C00000499B06C04A9904C04C9979 +:1039800002C00E94851389E189831C821C8E1BA2C0 +:103990001EA28E010F5F1F4FC80161E00E94352FEC +:1039A000882309F49BC45DEA852E53E0952E1CD52F +:1039B000499906C04A9904C04C9B02C00E946B14EE +:1039C000C8010E943506C8010E94480822243324F9 +:1039D0008091A003882309F078C0F894D0909A03CE +:1039E000C0909C0310929F0378948091A103882338 +:1039F00009F07EC080919F03882351F74B9B04C040 +:103A000007996DC0F1010995499918C080916A0321 +:103A100090916B03009771F3019790936B038093E0 +:103A20006A03C8010E9448088FEF94E3ACE081501C +:103A30009040A040E1F700C00000DCCF4A9B49C0A5 +:103A40004C99D8CF80919803813009F405C3823016 +:103A500009F499C280916800886080936800809121 +:103A6000680084608093680080916800846080931F +:103A700068008091680081608093680010929A03CA +:103A80002ED60E949614882309F4A2CF8091A20317 +:103A900091E089279091A303992309F4826082B968 +:103AA000459AA7E8B3E11197F1F700C000004598E7 +:103AB000B2E4BA95F1F700C04298E1E0E093A103C7 +:103AC0008091A003882309F488CF8DEA93E0AFD8D2 +:103AD00084CF80916A0390916B0301969ECF89B148 +:103AE00080FF90CF86B180FF8DCF31998DCF8ACF67 +:103AF000ED2CFF242DB73EB7285030400FB6F89478 +:103B00003EBF0FBE2DBFEDB7FEB73196ADB7BEB706 +:103B100012969C928E92119726E1422E512C53823E +:103B2000428294E1692E93E0792E75826482F78255 +:103B3000E6820E94483E2DB73EB7285F3F4F0FB642 +:103B4000F8943EBF0FBE2DBF88E164E090D4C4015D +:103B500060E044E598D4AC2CBB248DB79EB70897A1 +:103B60000FB6F8949EBF0FBE8DBFEDB7FEB731966E +:103B7000ADB7BEB712969C928E9211975382428235 +:103B800089E1482E83E0582E55824482B782A6826E +:103B90000E94483E2DB73EB7285F3F4F0FB6F894BE +:103BA0003EBF0FBE2DBF88E364E061D4C40160E076 +:103BB00044E569D480919B038D1509F4BDC16091E2 +:103BC0009B03C8013EDCD0929B03C0929D0380E022 +:103BD00090E0FC01EA53FA4C20812D7F208301966E +:103BE00088319105B1F780919F03882309F0F0CEC9 +:103BF00080919E03882309F091C13D2D303598F7BF +:103C00008091A303882309F0BCC1F701E45DFE4F56 +:103C100024918091A703821710F01092A70386B118 +:103C20004B9903C3881F8827881F8EAF2C9D902D2A +:103C3000112423969FAF2397A701440F551FCA0154 +:103C4000880F991F880F991F880F991F840F951F40 +:103C500028968FAF289729969FAF299730E02A9D05 +:103C6000C0012B9D900D3A9D900D11242C016624CE +:103C700057FC6094762C27964CAE5DAE6EAE7FAE50 +:103C800027970E2CEF2C000CEE1CFF08000CEE1CEE +:103C9000FF1CAA0CBB1CA294B294E0EFBE22BA2473 +:103CA000AE22BA245E2C5A285FAE852D90E084584F +:103CB0009E4F44575F4FFA01659074902B967FAEEC +:103CC0006EAE2B972D2D2F7321962FAF2197E22FBC +:103CD000F0E0E458FE4F34912C963FAF2C97FC0156 +:103CE000F4912D96FFAF2D972296DFAE22972E9658 +:103CF000CFAE2E972401F6B0F094FF1CFF24FF1CDA +:103D000009F474C16EAC6F1461F080E464E0AFD369 +:103D1000FF2009F491C186ED94E060E035D421E004 +:103D20002EAF8091AB03813009F48CC18091A30345 +:103D3000882309F40CC1E090A703F8946E2C772433 +:103D400076EC872E75E3972E860C971CD4018C9108 +:103D500081FDF0C08C9182FDEDC08C9184608C93CC +:103D600081E07894882309F441C08091A3038823DB +:103D700009F054C12B966EAD7FAD2B978091A703B0 +:103D8000A0900936B0900A36C0900B36D0900C3611 +:103D9000A80EB11CC11CD11C27968CAD9DADAEAD3B +:103DA000BFAD2797A80EB91ECA1EDB1E80E090E0AB +:103DB0002091A60330E040E050E00E94893DA60E2D +:103DC000B71EC81ED91E0CD38091C335882309F4B1 +:103DD00013C1C801B601A5012E2DE9DA05D3D4011E +:103DE0008C9182608C938C918B7F8C938091A703B4 +:103DF000882301F5FF2059F085B1B8E08B2785B9FC +:103E00008091AB03823018F081508093AB032091F6 +:103E1000AA03275E2093AA032D3708F008C130E0DB +:103E20008091A8039091A903821B930B9093890022 +:103E3000809388008091A303882309F48FC052E304 +:103E4000F52E05C08EE40E94FF10FA9431F08091A7 +:103E50009F038823B9F34201BBCD80919F03882340 +:103E6000D1F70E94FF10F394EF2DEC30B1F72FEF54 +:103E70003FEF3093A5032093A4030E94DA100E9421 +:103E8000DA100E94DA1080919F03882321F78EEFC9 +:103E90000E94FF1080919F038823E9F622968FAD40 +:103EA00022970E94FF1080919F038823A1F62E96EF +:103EB0008FAD2E970E94FF1080919F03882359F6A3 +:103EC0008091A7038F5F0E94FF1080919F0388233A +:103ED00011F682E00E94FF10F090A4038091A503E8 +:103EE00090919F03992309F0B6CF0E94FF10809113 +:103EF0009F03882309F0AFCF8F2D0E94FF10FF246E +:103F000008C08EE40E94FF10F3943F2D363109F46F +:103F1000A8C180919F038823A1F39DCF80E464E032 +:103F2000A6D28CED94E060E02FD380919F0388238C +:103F3000E1F359CE80E015CF8091A303882309F4E3 +:103F400052CE80919D038C1509F039CE4CCEE09075 +:103F5000A70323963FAD2397E30EEFCE27E3E22E90 +:103F6000F12C0AC08FEF0E94CB100894E108F108F1 +:103F7000E114F10409F489C080919F03882391F32F +:103F80006ACF22E146CE80919903815080939903B4 +:103F9000C80161E00E94BB2E80919903882389F0BB +:103FA000FF249F2DADE09A9FB00111246D537E4CEC +:103FB000C80141E00E94D92EF39480919903F8162C +:103FC00080F310926B0310926A0389D3C8010E9498 +:103FD0003506C8010E9448088FEF99E6A8E1815094 +:103FE0009040A040E1F700C00000F2CCC80122964A +:103FF0006FAD229726DA86CE9301322F2227330F18 +:104000002D533C4FC801B601A501EED4882309F019 +:10401000E5CE89EF91E00E941716E0CE28969FAD7D +:10402000289729968FAD2997692F782FA7CE1092C0 +:10403000AA0320E030E0F4CE80ED94E060E0A4D26A +:104040002B9A1EAE1092AB0380E065E010D28AEB93 +:1040500094E060E099D26ACEF0909903AF2DBDE074 +:10406000AB9FC00111248D539E4C6CE673E04DE074 +:1040700050E00E94393EF394F0929903C8016CE637 +:1040800073E041E00E94D92E9CCF8091A60382303C +:1040900009F4E4C082E0F82EE090A70380919F032A +:1040A000882309F0D8CE85ED0E94CB1080919F0324 +:1040B000882309F0D0CE8AEA0E94CB1080919F031A +:1040C000882309F0C8CE86E90E94CB1080919F0317 +:1040D000882309F0C0CE2C968FAD2C970E94CB1070 +:1040E00080919F03882309F0B6CEE091A703F0E00A +:1040F000E458FE4F84910E94CB1080919F03882347 +:1041000009F0A9CE2D968FAD2D970E94CB108091EE +:104110009F03882309F09FCEEF2DF0E0E458FE4F77 +:1041200084910E94CB1080919F03882309F093CE45 +:104130002196EFAD2197EE252FADE227EF25EF7306 +:10414000F0E0E458FE4F84910E94CB1080919F03D1 +:10415000882309F080CE8EED0E94CB1080919F03C2 +:10416000882309F078CE8AEA0E94CB10BAE0FB2EB1 +:1041700080919F03882309F06ECE8FEF0E94CB10B1 +:10418000FA94B1F780919F03882309F064CE85EDFE +:104190000E94CB1080919F03882309F05CCE8AEAAD +:1041A0000E94CB1080919F03882309F054CE8DEAA2 +:1041B0000E94CB1080919F03882309F04CCEE091A0 +:1041C000A703F0E0E458FE4F84910E94CB10C30196 +:1041D000982F8827990F8D539C4F0E94261180910C +:1041E0009F03882309F037CE8EED0E94CB1080917B +:1041F0009F03882309F02FCE8AEA0E94CB1080917A +:104200009F03882309F027CE8FEF0E94CB102296C0 +:104210008FAD22976091A70395D88093A7034B9BFE +:104220006ACD2296DFAC229742014598429A1092BD +:10423000A103C8016D2D05D98FE79AE1A6E0815051 +:104240009040A040E1F700C000000E94BF15C801E7 +:104250000E943506C8010E944808BACB92E2F92EA6 +:104260001BCF4CE0F42E80919F03882309F0F3CDFF +:104270000E94FF10FA94B9F78FEF9FEF9093A50378 +:104280008093A4030E94DA100E94DA100E94DA10D0 +:1042900080919F03882309F0DECD8BEF0E94FF10F1 +:1042A0006301DC2CCC24DD0CA3ECB3E0CA0EDB1ED6 +:1042B000EE24FF240BC00E94FF100894E11CF11CA7 +:1042C000F0E0EF16F2E0FF0609F468C0F601819114 +:1042D0006F0190919F03992371F3BDCD00D000D061 +:1042E00000D0EDB7FEB731964DEA842E43E0942E10 +:1042F000ADB7BEB712969C928E92119736E1E32E1F +:10430000F12CF382E28287EF92E0958384830E940E +:10431000483EF40101900020E9F73197E819F909C6 +:104320002DB73EB72A5F3F4F0FB6F8943EBF0FBE82 +:104330002DBF8E2F8195880F865D64E098D0C401D3 +:1043400060E044E5A0D08DB79EB70A970FB6F89409 +:104350009EBF0FBE8DBFEDB7FEB73196ADB7BEB7EE +:1043600012969C928E921197F382E28283E093E000 +:10437000958384838981868317828B8180871186C8 +:104380000E94483EEDB7FEB73A960FB6F894FEBFCE +:104390000FBEEDBF80E00E94240A09CBF090A40379 +:1043A0008091A50390919F03992309F054CD0E9419 +:1043B000FF1080919F03882309F04DCD8F2D0E941F +:1043C000FF1025CF81E090E00C94110A80E090E08E +:1043D0000C94110A14BC83E085BD81E085BB08956F +:1043E00081E080936E00089510926E0008951F92F0 +:1043F0000F920FB60F9211248F939F93AF93BF9399 +:104400008091113690911236A0911336B0911436E6 +:104410000196A11DB11D8093113690931236A09381 +:104420001336B0931436BF91AF919F918F910F9037 +:104430000FBE0F901F9018952FB7F894609111360A +:104440007091123680911336909114362FBF0895D3 +:1044500090E59CBD1DBC882341F05E9A2A986EBDF4 +:104460000DB407FEFDCF2A9A08955E98F7CF1F93EB +:10447000162F682F606880E0EBDF612F606480E0BA +:10448000E7DF1F910895AF92BF92CF92DF92EF9234 +:10449000FF920F931F93CF93DF93D62EC42EE82E57 +:1044A000F92EBB248FE7A82EF70101917F0100238D +:1044B00059F4DF91CF911F910F91FF90EF90DF9012 +:1044C000CF90BF90AF900895BC1498F70D3609F1C6 +:1044D00083E0089F80011124E801C85FD84F065F80 +:1044E000184FFE016491660FD1106A2581E0B0DF9C +:1044F000B394C017D10749F4BC14B0F6DD20C1F164 +:104500006FE781E0A5DFB394CFCF2196BC1460F6AE +:10451000E8CFDD2079F163E481E09ADFB394BC1445 +:1045200008F0C2CFDD2051F16BE781E091DFB39459 +:10453000BC1408F0B9CFDD2029F167E681E088DFFF +:10454000B394BC1408F0B0CFDD20D1F06BE781E06C +:104550007FDFB394BC1408F0A7CFDD2069F067E4D7 +:1045600081E076DFB394BC1408F09ECFDD2041F6E5 +:1045700060E0C7CF6CE3D0CF68E3F2CF64E0D5CF83 +:1045800064E0E5CF68E1DACFCF92DF92EF92FF925D +:104590000F931F93CF93DF93D62E8C010F5F1F4F86 +:1045A0002FE7C22EF8013197E491EE2331F1ED3679 +:1045B00079F183E0E89FF0011124EF01C85FD84F43 +:1045C0009BE0E92E97E0F92EEE0EFF1EFE016491AE +:1045D000660FD1106C2581E03BDF2196CE15DF05FB +:1045E000A9F7DD2099F06FE781E032DF0F5F1F4F01 +:1045F000F8013197E491EE23D1F6DF91CF911F912D +:104600000F91FF90EF90DF90CF90089560E0ECCF96 +:10461000DD2089F081E063E41BDF81E06BE718DFD8 +:1046200081E067E615DF81E06BE712DF81E067E498 +:104630000FDF6FE7D9CF81E06CE30ADF81E064E050 +:1046400007DF81E068E104DF81E064E001DF81E011 +:1046500068E3FEDE60E0C8CFEF92FF920F931F93F6 +:10466000CF93DF93E82EF92EF70101917F0100230C +:10467000E1F00D3609F183E0089F80011124E80183 +:10468000C85FD84F055F184FFE016491606481E0F8 +:10469000DFDE2196C017D107B9F781E060E4D8DEEC +:1046A000F70101917F01002321F7DF91CF911F9145 +:1046B0000F91FF90EF90089581E06EE5C9DE81E0F3 +:1046C00062E4C6DE81E06CE4C3DE81E062E4C0DE69 +:1046D00081E06CE5BDDE81E060E4BADEC5CFCF935A +:1046E000DF93C8EFD1E081E060E0B2DE2197D9F737 +:1046F000DF91CF91089584EB8093153684E1809308 +:10470000163684E080931736569A279A259A229A6D +:10471000209A2A9880E090E00E948840813FE1F052 +:1047200080E090E061EF0E9490406091153681E05A +:1047300090E00E94904080E061E28ADE6091153650 +:1047400080E086DE6091163680E082DE80E060E206 +:104750007FDE80E06CE07CCE81E090E00E948840CB +:1047600080931536E8CFFC014181842F90E09C01B5 +:104770003595279520652CBD40FD06C081E046306B +:1047800019F08DBD2C98089580E08DBD2C9808956A +:10479000BF92CF92DF92EF92FF920F931F93CF932E +:1047A000DF938C016B017A0147DEEB01BB24BA94E5 +:1047B000BEBC0DB407FEFDCF8EB5F80182838F3FDE +:1047C000B1F43ADE6C1B7D0B81E06D32780780F32B +:1047D00081E1F80180832C9A80E0DF91CF911F91D5 +:1047E0000F91FF90EF90DF90CF90BF9008958E3F94 +:1047F00019F08FE08083EFCFE114F104F1F0089419 +:10480000E108F1088FEF8EBDE114F10471F0F601BB +:1048100080E090E03FEF0DB407FEFDCF2EB5219371 +:104820003EBD01968E159F05B0F30DB407FEFDCF7A +:104830008EB5F601EE0DFF1D80838FEF8EBD0DB49A +:1048400007FEFDCF8EB58FEF8EBD0DB407FEFDCFF9 +:104850008EB52C9A81E0C1CF0F931F93CF93DF9336 +:10486000EC018B0180DFCE01B80140E052E090DF27 +:10487000DF91CF911F910F910895FF920F931F9396 +:10488000CF93DF93EB01D8DD8B01FF24FA94FEBCBC +:104890000DB407FEFDCF8EB58F3F69F0CDDD601BF7 +:1048A000710B6C177D0798F380E0DF91CF911F911A +:1048B0000F91FF90089581E0DF91CF911F910F91AB +:1048C000FF900895DF92EF92FF920F931F93CF9383 +:1048D000DF93EC01D62E79018A0145DFCE016CE22F +:1048E00071E0CBDF8D2D80648EBD0DB407FEFDCF52 +:1048F00028E130E0D801C701022E04C0B695A79583 +:10490000979587950A94D2F78EBD0DB407FEFDCF1B +:10491000285030408FEF283F380761F7DD20E9F05D +:104920008D2D883001F587E88EBD0DB407FEFDCFD3 +:104930008D2D8C30D1F02FEF9FEF9EBD0DB407FE73 +:10494000FDCF8EB58A8387FD0AC0DF91CF911F917D +:104950000F91FF90EF90DF90089585E9E5CF222336 +:10496000A1F32150EACF8FEFDFCF8FEF8EBD0DB4D3 +:1049700007FEFDCF8EB5DFCFCF93DF93EC01F3DEE3 +:10498000CE016CE020E030E0A9019CDF882339F003 +:1049900083E088832C9A80E0DF91CF9108952C9A50 +:1049A00081E0DF91CF910895CF93DF93EC019A01DD +:1049B000AB018B81833039F069E0220F331F441F34 +:1049C000551F6A95D1F7CE0162E17CDF882339F06B +:1049D00085E088832C9A80E0DF91CF9108952C9A0E +:1049E00081E0DF91CF910895CF92DF92EF92FF9215 +:1049F0000F931F93CF93DF93EC017A018B01690131 +:104A00008B81833039F0A9E0EE0CFF1C001F111FD1 +:104A1000AA95D1F7CE0161E1A801970153DF882360 +:104A200069F084E088832C9A80E0DF91CF911F9118 +:104A30000F91FF90EF90DF90CF900895CE01B601D7 +:104A400040E052E0A5DEF1CF8F929F92BF92CF92CD +:104A5000DF92EF92FF920F931F93DF93CF930F920A +:104A6000CDB7DEB74C01B62EFC0113821082E4DC18 +:104A70008B01249A2C9A2698259A279A249A2C9A64 +:104A800085E0F401818382E58CBD1DBC8AE09FEF47 +:104A90009EBD0DB407FEFDCF8150D1F7C40160E08B +:104AA00020E030E0A9010EDF782FF401828381300D +:104AB000C9F0C2DC601B710BF7E0613D7F0770F34A +:104AC00081E0F40180832C9A80E00F90CF91DF91F8 +:104AD0001F910F91FF90EF90DF90CF90BF909F902C +:104AE0008F900895C40168E02AEA31E040E050E088 +:104AF0007983E8DE798182FF1FC0F4017383CC24BF +:104B0000DD247601C40167E320E030E0A901DADEAC +:104B1000C40169E2A7019601D5DEF40182838823EE +:104B2000D9F08ADC601B710BF7E0613D7F0750F321 +:104B30008AE0F4018083C7CF84E02FEF2EBD0DB44F +:104B400007FEFDCF9EB5F40192838150B9F79A3AE2 +:104B500079F082E08083B7CF83818230B1F02C9AE4 +:104B6000FB2DF73070F088E1F401808380E0ADCF59 +:104B700082E0F4018383C12CD12CE12CB0E4FB2E24 +:104B8000C1CFF401B18281E0A0CFC4016AE320E08B +:104B900030E0A90197DE882321F088E0F4018083CA +:104BA00092CF8FEF8EBD0DB407FEFDCF8EB5807C0A +:104BB000803C19F483E0F401838383E09FEF9EBD82 +:104BC0000DB407FEFDCF2EB58150C9F7C8CFFC014B +:104BD0006EBDA42FB52F80E090E00DB407FEFDCF91 +:104BE0002C912EBD0DB407FEFDCF11962C9111977F +:104BF0002EBD0296129622E08030920771F70DB416 +:104C000007FEFDCF8FEF8EBD0DB407FEFDCF8FEFFA +:104C10008EBD0DB407FEFDCF8FEF8EBD0DB407FE28 +:104C2000FDCF8EB582838F71853029F083E180833B +:104C30002C9A80E0089581E008950F931F93CF93FD +:104C4000DF93EC018B018FDDCE0168E572E015DEAC +:104C5000882349F485E188832C9A80E0DF91CF9105 +:104C60001F910F910895CE016CEFA801B0DF88234A +:104C700089F32C9A81E0DF91CF911F910F910895D4 +:104C8000CF92DF92EF92FF920F931F93CF93DF9318 +:104C9000EC017A018B0169018B81833039F089E065 +:104CA000EE0CFF1C001F111F8A95D1F7CE0168E1A1 +:104CB000A801970107DE882369F086E088832C9A93 +:104CC00080E0DF91CF911F910F91FF90EF90DF90E7 +:104CD000CF900895CE016EEFA60179DF882379F396 +:104CE000CE0168E572E0C9DD882319F487E1888385 +:104CF000E6CFCE016DE020E030E0A901E3DD8823BE +:104D000019F086E18883DBCF8FEF8EBD0DB407FEEF +:104D1000FDCF8EB58823A9F72C9A81E0D2CFAF9230 +:104D2000BF92CF92DF92EF92FF920F931F93CF9398 +:104D3000DF93EC015A016B017801890167E320E000 +:104D400030E0A901BFDDCE0167E1A8019701BADD1E +:104D5000882379F089E088832C9A80E0DF91CF91D5 +:104D60001F910F91FF90EF90DF90CF90BF90AF9089 +:104D700008958B81833039F099E0AA0CBB1CCC1CC0 +:104D8000DD1C9A95D1F7CE0169E1A60195019ADD66 +:104D9000882319F087E08883DFCF2C9A81E0DECF6B +:104DA000CF93DF93EC01DFDCCE0168E572E065DDD7 +:104DB000882359F08DEF8EBD0DB407FEFDCFCE01D7 +:104DC00068E572E05ADD882339F482E188832C9A01 +:104DD00080E0DF91CF9108952C9A81E0DF91CF910F +:104DE0000895CF93DF93EC019C012C5F3F4F898D99 +:104DF0009A8D41E050E060E070E00E9483318823AA +:104E0000D9F08D899E89AF89B88D0097A105B1052C +:104E100079F48C819D81AE81BF818D8B9E8BAF8B10 +:104E2000B88F89818068898381E0DF91CF9108956F +:104E300081E0DF91CF91089580E0DF91CF910895D7 +:104E4000CF92DF92EF92FF921F93CF93DF93EC010B +:104E500089899A89AB89BC89803E2FEF92072FE11F +:104E6000A20720E0B20748F080E0DF91CF911F91C8 +:104E7000FF90EF90DF90CF900895CE01B2DF8823AE +:104E800099F30E94572F882379F3E98DFA8DCC800E +:104E9000DD80EE80FF808EEF9FEFAFEFBFEFC80E9B +:104EA000D91EEA1EFB1E058404C0CC0CDD1CEE1CC2 +:104EB000FF1C0A94D2F786859785A089B189C80E10 +:104EC000D91EEA1EFB1E81E080932438C0921E3654 +:104ED000D0921F36E0922036F092213680E092E0A8 +:104EE000E2E2F6E3DF019C011D9221503040E1F740 +:104EF000E98DFA8D84818230C0F011E006C01F5F19 +:104F0000E98DFA8D8481181780F4B701A601410F4D +:104F1000511D611D711D809122389091233822E22C +:104F200036E3AEDE882359F79FCF20E032E040E041 +:104F300050E0058404C0220F331F441F551F0A94FC +:104F4000D2F789899A89AB89BC89820F931FA41FE4 +:104F5000B51F898B9A8BAB8BBC8B81E086CFCF93AF +:104F6000DF93EC018C859D85AE85BF8541E066238E +:104F700009F440E0BC01CD01DAD7882381F028890B +:104F800030E0220F331F22953295307F3227207F69 +:104F900032272E5D394CC901DF91CF91089520E071 +:104FA00030E0C901DF91CF9108956F927F928F9287 +:104FB0009F92AF92BF92CF92DF92EF92FF920F93A8 +:104FC0001F93DF93CF9300D000D0CDB7DEB76C0135 +:104FD0004B013A01DC015596ED90FD900D911C912D +:104FE0005897E114F10401051105F1F05E010894F0 +:104FF000A11CB11C10C0D801C7010196A11DB11D93 +:1050000029813A814B815C8182179307A407B507F8 +:10501000F9F47C018D01F601818D928DB801A70113 +:105020009501CAD7882339F780E00F900F900F9031 +:105030000F90CF91DF911F910F91FF90EF90DF9034 +:10504000CF90BF90AF909F908F907F906F9008957A +:10505000D60159966D917C915A97FB0187898031D1 +:1050600009F44CC0283F8FEF38078FEF48078FE0D7 +:105070005807D0F2F60185899689A789B08D0297E5 +:10508000A109B109FB01058404C0880F991FAA1F5B +:10509000BB1F0A94D2F72685378540895189820F34 +:1050A000931FA41FB51FF40180839183A283B38350 +:1050B000FB0186859785A089B1890197A109B1096E +:1050C0002481820F911DA11DB11DA80197012250BD +:1050D000304040405040058404C0220F331F441F1D +:1050E000551F0A94D2F7820F931FA41FB51FF30117 +:1050F00080839183A283B38381E097CF283FFFEF22 +:105100003F07F0E04F07F0E05F0708F0B3CF8CCF28 +:10511000E82FF92F80E090E03EE209C0DB01A90F03 +:10512000B11D2C939F5F8F5F31968B3061F0208192 +:105130002032C9F3883091F7DB01A90FB11D3C93F0 +:105140009F5F2081EBCF690F711DFB0110820895D5 +:105150001F93FB012BE030E231932150E9F7A82F98 +:10516000B92F30E017E09A2F8B2F2D91222351F485 +:10517000FA019083818381E0FB019081903279F084 +:105180001F9108952F32A1F32E3261F085E898E047 +:10519000FC010196E491EE2351F02E17C9F780E04F +:1051A0001F9108951A30D9F338E01AE0DCCF1317B5 +:1051B000B0F32132A0F32F3790F7FB01E30FF11D7D +:1051C000822F81568A3108F4205220833F5FCBCF53 +:1051D0000F931F93CF93DF93EC018B018B81882377 +:1051E00031F4FB018789803141F08032F1F180E0B8 +:1051F000DF91CF911F910F91089582E08B831D8ADB +:105200001E8A1F8A188E808D918DA0E0B0E0880FD5 +:10521000991FAA1FBB1F880F991FAA1FBB1F880FAA +:10522000991FAA1FBB1F880F991FAA1FBB1F880F9A +:10523000991FAA1FBB1F898B9A8BAB8BBC8B1A8FB4 +:10524000098F81E089831C821D821E821F8218863D +:1052500019861A861B861C861D861E861F86188A3E +:10526000DF91CF911F910F91089583E08B83F80117 +:10527000428D538D648D758D4D8B5E8B6F8B788FCA +:105280009E012F5E3F4FC80124D78823C1F6AFCFC0 +:105290002F923F924F925F926F927F928F929F9246 +:1052A000AF92BF92CF92DF92EF92FF920F931F9334 +:1052B000CF93DF938C01362FE72F2A01DC01139661 +:1052C0002C911397222329F011968C91119780FD30 +:1052D00016C02FEF3FEFC901DF91CF911F910F91C2 +:1052E000FF90EF90DF90CF90BF90AF909F908F9006 +:1052F0007F906F905F904F903F902F900895E801BE +:10530000C988DA88EB88FC88488559856A857B8559 +:105310004201AA24BB24D701C601841B950BA60B0E +:10532000B70B88169906AA06BB0608F093C041146D +:10533000510409F4BEC0832E9E2E6201A4E02A2EE1 +:10534000312C200E311E612CF2E07F2E60C0FF2038 +:1053500009F07AC0411551056105710509F0ABC02E +:10536000E8018D899E89AF89B88D8C839D83AE833A +:10537000BF8346855785608971894F0D511D611D19 +:10538000711D0297A109B109058404C0880F991FF6 +:10539000AA1FBB1F0A94D2F7480F591F6A1F7B1F11 +:1053A000E301CA19DB09CC16DD0608F4E601E2E0E8 +:1053B000C030DE0709F452C0CB01BA0140E0B7D5D6 +:1053C000882309F486CF95012E5D394CC401B901BB +:1053D000AE010E94223EAE0160E070E0F8018085DF +:1053E0009185A285B385480F591F6A1F7B1FD8017D +:1053F00018964D935D936D937C931B97CC1ADD0AA1 +:1054000009F457C08C0E9D1E13962C911397EFEF45 +:10541000AE2EE1E0BE2EA422B5222230B9F1D80191 +:105420005996ED91FC915A97DB01CA0129E0B69596 +:10543000A795979587952A95D1F7F480FA94F82245 +:10544000A114B10409F483CFE8018C819D81AE8160 +:10545000BF818FCF2601441A550A69CF80911E362D +:1054600090911F36A0912036B091213648175907E8 +:105470006A077B0709F4A0CF8091223890912338E6 +:105480009401B2DA882309F0A6CF23CF39E07695CC +:105490006795579547953A95D1F7E801E98DFA8DCB +:1054A000828D938DA48DB58D480F591F6A1F7B1F68 +:1054B00077CF920110CFD80114964D915D916D91E7 +:1054C0007C911797CF01910177D5882309F401CFFB +:1054D000E801E98DFA8D8C819D81AE81BF8149CF34 +:1054E000DF93CF930F92CDB7DEB7BE016F5F7F4FD3 +:1054F00041E050E0CDDE8130910539F02FEF3FEFF4 +:10550000C9010F90CF91DF910895298130E0C90141 +:105510000F90CF91DF910895EF92FF920F931F9319 +:10552000CF93DF93EC018B81823050F420E030E0A8 +:10553000C901DF91CF911F910F91FF90EF900895D6 +:10554000E884F9840A851B85CE01CADF97FDEECF7A +:1055500088859985AA85BB854F96A11DB11D888731 +:105560009987AA87BB87D801C70115E0B695A7958B +:10557000979587951A95D1F78F70282F30E0220FD5 +:10558000331F22953295307F3227207F32272E5DC0 +:10559000394CCECF8F929F92AF92BF92CF92DF9233 +:1055A000EF92FF920F931F93CF93DF93EC014A0189 +:1055B0005B012B81222309F465C089899A89AB8913 +:1055C000BC8984179507A607B70708F45BC022308B +:1055D00009F452C081149104A104B10409F46AC011 +:1055E000488559856A857B85E98DFA8D258530E06A +:1055F000275F3F4FDB01CA010197A109B109022EC4 +:1056000004C0B695A795979587950A94D2F785011A +:1056100074010894E108F1080109110904C0169504 +:105620000795F794E7942A95D2F7E816F9060A0742 +:105630001B07B0F58D899E89AF89B88D8C839D83BA +:10564000AE83BF8384E0C82ED12CCC0EDD1E0FC0EC +:105650004C815D816E817F81898D9A8D9601ACD45C +:105660000894E108F10801091109882359F0E114AF +:10567000F1040105110561F788869986AA86BB8623 +:1056800081E001C080E0DF91CF911F910F91FF90E9 +:10569000EF90DF90CF90BF90AF909F908F90089544 +:1056A000411551056105710529F2E81AF90A0A0B3D +:1056B0001B0BC8CF1C821D821E821F821886198672 +:1056C0001A861B8681E0DFCF0F931F93CF93DF9362 +:1056D000EC018B81882349F0898187FD0EC0E7D3D7 +:1056E000DF91CF911F910F91089581E0888380E031 +:1056F000DF91CF911F910F910895CE0161E02FDCD2 +:105700008C01009791F3FC018081853E71F38B81C0 +:105710008230F8F08D899E89AF89B88DF801938F1A +:10572000828FB58BA48BE0911A36F0911B3630979F +:1057300059F0B8016A5E7F4FC80148960995F80193 +:10574000808D918D938B828B89818F778983AFD365 +:10575000C7CF89899A89AB89BC89848F958FA68F99 +:10576000B78FD8CFCF93DF93EC01AEDF1B82DF91F1 +:10577000CF9108956F927F928F929F92AF92BF9236 +:10578000CF92DF92EF92FF920F931F93DF93CF930D +:1057900000D000D0CDB7DEB77C015A016B01DC012F +:1057A00013968C9113978130A1F080E00F900F90A9 +:1057B0000F900F90CF91DF911F910F91FF90EF907D +:1057C000DF90CF90BF90AF909F908F907F906F9021 +:1057D000089511968C91119781FFE7CFF701818988 +:1057E0009289A389B48984179507A607B707E8F2B9 +:1057F0000097A105B10529F1F701608471848284C5 +:105800009384C701B601A501C5DE882371F2A114F6 +:10581000B104C104D104B9F4D70155964D915D91FD +:105820006D917C91589759968D919C915A97A3D6DA +:10583000882309F4BACFF701158A168A178A108EC1 +:1058400040C081E0B3CFD70114964D915D916D9129 +:105850007C91179759968D919C915A979E012F5F35 +:105860003F4FAAD3882309F4A0CFD7015996ED91D1 +:10587000FC915A9749815A816B817C81878980315B +:10588000C9F1483F8FEF58078FEF68078FE078071F +:10589000C0F4CF0170D6882309F487CFD7011496BE +:1058A0004D915D916D917C91179759968D919C9139 +:1058B0005A970FEF1FEF2FEF3FE086D4882309F4AC +:1058C00074CFF701A18AB28AC38AD48A81818068A1 +:1058D0008183C701F9DE882309F467CFB601A501EA +:1058E0006A147B048C049D0410F4B401A301C70165 +:1058F00051DE5CCF483FBFEF5B07B0E06B07B0E025 +:105900007B07F8F6C6CF1F93CF93DF93EC01142FDC +:10591000E62FF0E0EE0FFF1FE295F295F07FFE27F5 +:10592000E07FFE27DF01AE5DB94C1B968C911B9783 +:10593000817149F0842F827131F01B8280E0DF9108 +:10594000CF911F91089580911E3690911F36A0919E +:105950002036B09121368C879D87AE87BF87688BB4 +:10596000EE5DF94C84899589A0E0B0E0DC019927CF +:1059700088278D8B9E8BAF8BB88F428D538D60E0C7 +:1059800070E0482B592B6A2B7B2B4D8B5E8B6F8BDA +:10599000788F838590E0887190700097F1F4848D02 +:1059A000958DA68DB78D898B9A8BAB8BBC8B81E047 +:1059B0008B83812F8F7089831C821D821E821F82A0 +:1059C000188619861A861B8614FD17C015FD1EC081 +:1059D00081E0DF91CF911F9108958031910509F009 +:1059E000ACCF9E012F5E3F4F898D9A8D72D3882355 +:1059F00009F4A3CF84E08B83DCCFCE0140E050E0FC +:105A0000BA01B8DE882311F780E099CF49895A8915 +:105A10006B897C89CE01BEDD92CF8F929F92AF922F +:105A2000BF92CF92DF92EF92FF920F931F93CF938B +:105A3000DF935C01EB01C42E952E822E898D9A8D09 +:105A4000D5015A969C938E935997CB0140E050E034 +:105A5000BA01A0DDDD24E884F9840A851B858989E3 +:105A60009A89AB89BC89E816F9060A071B0708F072 +:105A700040C0CE0151DDFC01009709F476C0D80189 +:105A8000C70115E0B695A795979587951A95D1F713 +:105A9000182F1F708081882391F0853E81F08C2D16 +:105AA000992DBF014BE050E00E94153E009799F6FA +:105AB00087FC5BC0C501612F482D25DF57C0DD2065 +:105AC000A9F420911E3630911F3640912036509116 +:105AD0002136D5011C962D933D934D935C931F97D2 +:105AE00050961C9350978081DD24D394882309F02D +:105AF000B2CF86FE3AC081FE38C0DD2009F043C037 +:105B00008B81823091F1CE019BD9882371F1C2E261 +:105B1000D6E310E07E01EC2FFF2D80E2DF011D9225 +:105B20008A95E9F7DE018C2D992DFC018BE001901F +:105B30000D928150E1F7E0911A36F0911B363097C3 +:105B400061F1BE01625F7F4FCE0140960995888961 +:105B500099892E853F859B8B8A8B998F888F3F8B68 +:105B60002E8BA5D1882309F0A5CF80E0DF91CF91BE +:105B70001F910F91FF90EF90DF90CF90BF90AF906B +:105B80009F908F900895F5011089C50161E0E7D9D4 +:105B9000EC01009709F0BECFE8CF81E298E2998B43 +:105BA000888B80E098E09F878E8720E038E081E254 +:105BB00098E2D1CF2F923F924F925F926F927F9255 +:105BC0008F929F92AF92BF92CF92DF92EF92FF920D +:105BD0000F931F93DF93CF93CDB7DEB7C454D0405C +:105BE0000FB6F894DEBF0FBECDBF2C013B018E0176 +:105BF0000E5B1F4FD80111965C934E9325962FAFE5 +:105C000025971C861F861FA21AA66115710509F427 +:105C10005FC0FC018381882309F05AC0CA01DA0100 +:105C20002C912F3209F470C073013CE0832E912C2B +:105C30008C0E9D1E64015E010894A11CB11C27E21C +:105C4000222E312C2C0E3D1EB501A80181DA8823AD +:105C500069F1D801ED91FC91119780818F3241F467 +:105C60003196D8011196FC93EE9381918F32C9F34E +:105C7000882309F46FC0C601B701A50121E0CDDE7C +:105C80008823A1F0E614F70421F0C7011DDDF70118 +:105C90001382C814D904C9F076016401D8018D912A +:105CA0009C91B501A80154DA882399F600E08AA5F1 +:105CB000882321F0CE01879607DD1AA68F858823D9 +:105CC00041F0CE010C9600DD04C061017401E6CF05 +:105CD00000E0802FCC5BDF4F0FB6F894DEBF0FBE25 +:105CE000CDBFCF91DF911F910F91FF90EF90DF908B +:105CF000CF90BF90AF909F908F907F906F905F906C +:105D00004F903F902F9008959A012F5F3F4FC90108 +:105D1000F80131832083D9014C912F5F3F4F4F32DF +:105D2000B1F3F30123812250223008F47DCF87E2C2 +:105D3000E82EF12CEC0EFD1ED30159966D917C914D +:105D40005A97C70145DA882309F4B0CFF80180815A +:105D500091816BCFC201B701A50125962FAD259783 +:105D60005CDE082FA4CFFB01242F609118367091C0 +:105D70001936AF011FCF0F931F93CF93DF93EC0121 +:105D8000662399F08C010E5D1F4F10931936009316 +:105D90001836C801E7DCBE016C5F7F4FC80118DA16 +:105DA000DF91CF911F910F9108958C010E5D1F4FD0 +:105DB000F0CFDF92EF92FF920F931F93DF93CF9379 +:105DC000CDB7DEB76C970FB6F894DEBF0FBECDBF70 +:105DD000FB01D42E19821C8220812F3229F122E26C +:105DE000E22EF12CE80EF91E8E010F5F1F4FC80145 +:105DF000B701AF0121E0DEDE8823F1F08C81823033 +:105E000070F1D701F8018BE101900D928150E1F71B +:105E1000DD2021F0F0921936E092183621E0C80119 +:105E20002C8FA0DC2C8D0CC021812223C1F6642F85 +:105E3000A2DF282F8C8102C08C8120E0882389F486 +:105E4000822F6C960FB6F894DEBF0FBECDBFCF91F8 +:105E5000DF911F910F91FF90EF90DF90089520E068 +:105E6000EDCF8E010F5F1F4FDACF0F931F93CF93AC +:105E7000DF938C010E942425882331F480E0DF9198 +:105E8000CF911F910F910895E8012496CE01B8019A +:105E900041E0CDD3882321F0C80161E06CDFEFCF72 +:105EA000CE01B80140E0C3D3882341F3F5CF809100 +:105EB0002438882311F481E0089540911E365091D2 +:105EC0001F36609120367091213680912238909152 +:105ED000233822E236E30E944026882321F14091B4 +:105EE000253850912638609127387091283841150F +:105EF00051056105710521F41092243881E008955F +:105F0000809122389091233822E236E30E94402685 +:105F1000882359F01092253810922638109227388D +:105F200010922838E9CF80E0089580E00895DF924C +:105F3000EF92FF920F931F937B018C01D42E8091DF +:105F40001E3690911F36A0912036B09121368E15C5 +:105F50009F05A007B107F1F0AADF882339F480E09C +:105F60001F910F91FF90EF90DF900895809122385C +:105F700090912338B801A70122E236E30E94F4246D +:105F8000882369F3E0921E36F0921F360093203684 +:105F900010932136DD2049F081E0809324381F9151 +:105FA0000F91FF90EF90DF90089581E01F910F9186 +:105FB000FF90EF90DF900895CF92DF92EF92FF92E3 +:105FC0000F931F93CF93DF93EC017A018B0169014B +:105FD00089859A85AB85BC850196A11DB11D841765 +:105FE0009507A607B70730F0EF89E03169F0E03296 +:105FF00009F445C080E0DF91CF911F910F91FF9090 +:10600000EF90DF90CF9008959927872F762F652FF7 +:106010002B893C894D895E89620F731F841F951FF0 +:1060200020911E3630911F364091203650912136F6 +:10603000621773078407950729F040E078DF88230B +:10604000C9F2EF89E03169F18FE790E0A0E0B0E0BC +:10605000E822F9220A231B23F701EE0FFF1FEE0FA0 +:10606000FF1FEE5DF94C80819181A281B381BF70E9 +:10607000F60180839183A283B38381E0BCCFCB01FF +:10608000BA0127E096958795779567952A95D1F778 +:106090002B893C894D895E89620F731F841F951F70 +:1060A000BFCF8FEF90E0A0E0B0E0E822F9220A2312 +:1060B0001B23F701EE0FFF1FEE5DF94C80819181EC +:1060C000A0E0B0E0F60180839183A283B38381E0F6 +:1060D00092CF4F925F926F927F928F929F92AF92E8 +:1060E000BF92CF92DF92EF92FF920F931F93DF93B5 +:1060F000CF9300D000D0CDB7DEB78C0149835A834F +:106100006B837C832901842F952FA62FB72FAC0199 +:10611000BD01CC24DD2476015E010894A11CB11CD4 +:10612000612CE2E07E2E812C912CC801950144DF88 +:10613000882309F447C0D401C301F801058404C0D1 +:10614000880F991FAA1FBB1F0A94D2F7C80ED91E29 +:10615000EA1EFB1E49815A816B817C8187898031CF +:1061600019F1483F8FEF58078FEF68078FE07807E6 +:10617000E0F2F201C082D182E282F38281E00F90EC +:106180000F900F900F90CF91DF911F910F91FF9083 +:10619000EF90DF90CF90BF90AF909F908F907F90C7 +:1061A0006F905F904F900895483FFFEF5F07F0E0DA +:1061B0006F07F0E07F07E8F6C8019501FDDE882350 +:1061C00009F0B9CF80E0DBCF4F925F926F927F9260 +:1061D0008F929F92AF92BF92CF92DF92EF92FF92F7 +:1061E0000F931F93CF93DF93EC016A017B0128018A +:1061F0003901423051056105710590F089859A8514 +:10620000AB85BC850196A11DB11D84179507A60716 +:10621000B70730F08F89803109F456C0803291F091 +:1062200080E0DF91CF911F910F91FF90EF90DF9071 +:10623000CF90BF90AF909F908F907F906F905F9026 +:106240004F9008954A015B0117E0B694A794979484 +:1062500087941A95D1F78B899C89AD89BE89880E60 +:10626000991EAA1EBB1EC501B40141E060DE882351 +:10627000B9F28F898031A9F18FE790E0A0E0B0E01A +:10628000C822D922EA22FB22F601EE0FFF1FEE0FF1 +:10629000FF1FEE5DF94C40825182628273828A89CF +:1062A000823078F18D819E81AF81B885880D991DEE +:1062B000AA1DBB1D8093253890932638A0932738BC +:1062C000B093283881E0ADCF852E962EA72EBB2423 +:1062D0008B899C89AD89BE89880E991EAA1EBB1E1A +:1062E000C2CF8FEF90E0A0E0B0E0C822D922EA222E +:1062F000FB22F601EE0FFF1FEE5DF94C518240824A +:10630000CECF81E08ECF2F923F924F925F926F92CD +:106310007F928F929F92AF92BF92CF92DF92EF9235 +:10632000FF920F931F93DF93CF93CDB7DEB767979D +:106330000FB6F894DEBF0FBECDBF1C0149875A8748 +:106340006B877C873E872D87FC0181859285A3859D +:10635000B4859C01AD012F5F3F4F4F4F5F4F2D83A1 +:106360003E834F835887ED85FE8540805180628053 +:106370007380411451046104710409F4BEC008948F +:10638000411C511C611C711C1F860097A105B105A1 +:1063900009F454C0D301C201CC24DD2476018E015E +:1063A0000F5F1F4F4C8A5D8A6E8A7F8A2EC04C0118 +:1063B0005D01C101B501A4019801FEDD882309F446 +:1063C0003DC089819A81AB81BC810097A105B1054F +:1063D00009F44EC0A50194012F5F3F4F4F4F5F4F0F +:1063E0002C8B3D8B4E8B5F8BDA01C9010894C11C4D +:1063F000D11CE11CF11CF1012185328543855485B6 +:10640000C216D306E406F506C8F44D805E806F80A0 +:106410007884481659066A067B0648F682E0882E7C +:10642000912CA12CB12C8C8A9D8AAE8ABF8AC10185 +:10643000B501A4019801C0DD882319F680E06796B4 +:106440000FB6F894DEBF0FBECDBFCF91DF911F9185 +:106450000F91FF90EF90DF90CF90BF90AF909F9003 +:106460008F907F906F905F904F903F902F90089506 +:10647000D501C4010196A11DB11D2C013D012C893E +:106480003D894E895F89421A530A640A750A298533 +:106490003A854B855C85421653066406750609F0FD +:1064A000A5CF4C885D886E887F88C101B501A401A5 +:1064B0000FEF1FEF2FEF3FE087DE882309F4BECFF9 +:1064C000481459046A047B0458F59501840107C0F7 +:1064D000970186014C145D046E047F0408F5680181 +:1064E00079010894C108D108E108F108C101B70198 +:1064F000A6016ADE882361F7A1CFF10140805180B7 +:1065000062807380F1E0FF8729853A854B855C8541 +:10651000213031054105510509F437CF1F8635CFAC +:10652000AD85BE854D915D916D917C91139741151F +:10653000510561057105C1F4ED85FE8540825182EA +:1065400062827382FF85FF2369F00894411C511C0D +:10655000611C711CD1014D925D926D927C921397DA +:1065600081E06DCF81E06BCFC101930182012CDE10 +:10657000882311F763CFAF92BF92CF92DF92EF9251 +:10658000FF920F931F93DF93CF9300D000D0CDB72E +:10659000DEB76C017A018B0182E090E0A0E0B0E010 +:1065A000F60180839183A283B3835E010894A11CCA +:1065B000B11CC601B801A7019501FEDC882339F1A1 +:1065C000C601B801A70100E010E09801FDDD8823B5 +:1065D000F1F0E980FA800B811C81F6018789803116 +:1065E00059F088EFE8168FEFF8068FEF08078FE075 +:1065F0001807F8F281E00CC0F8EFEF16FFEFFF0686 +:10660000F0E00F07F0E01F07A0F281E001C080E09A +:106610000F900F900F900F90CF91DF911F910F91DE +:10662000FF90EF90DF90CF90BF90AF9008956F9262 +:106630007F928F929F92AF92BF92DF92EF92FF92E2 +:106640000F931F93CF93DF93EC01142F7093233894 +:10665000609322381F8A82E090E0A0E0B0E0888357 +:106660009983AA83BB831092243810922538109204 +:10667000263810922738109228388FEF9FEFDC01D0 +:1066800080931E3690931F36A0932036B093213608 +:10669000442309F444C0453078F080E0DF91CF9185 +:1066A0001F910F91FF90EF90DF90BF90AF909F9060 +:1066B0008F907F906F90089560E070E0CB0140E094 +:1066C00036DC882351F3212F30E022953295307F3C +:1066D0003227207F32272E5E394CF901E254FE4FDB +:1066E000808190E08F7790700097B9F6F901E653BA +:1066F000FE4F80819181A281B38184369105A105ED +:10670000B10558F22A533E4FF901E080F180028131 +:106710001381E114F1040105110521F4BECFEE242B +:10672000FF248701C801B70140E001DC882309F498 +:10673000B4CF80912D3690912E36F2E080309F07B5 +:1067400009F0ABCF20913236222309F4A6CF8091F5 +:10675000303690913136009709F49FCF60912F36F3 +:10676000662309F49ACF2A8B6C831D8670E080E043 +:1067700090E041E050E008C0282F2F5F2D87019660 +:106780008930910509F489CFD82E9A01082E02C0CC +:10679000220F331F0A94E2F72617370769F7609133 +:1067A0003836709139366115710509F47FC080E083 +:1067B00090E06D837E838F839887809030369090B1 +:1067C0003136AA24BB248E0C9F1CA01EB11E8B8ABE +:1067D0009C8AAD8ABE8A6090333670903436798E4A +:1067E000688E2091323630E040E050E00E94893DD2 +:1067F000680D791D8A1D9B1D6A8F7B8F8C8F9D8FE5 +:106800009301220F331F22953295307F3227207F4C +:10681000322721503E4F232F3327269540E050E06A +:10682000260F371F481F591F2E873F87488B598BCC +:106830008091353690913636009709F440C0A0E03B +:10684000B0E0E21AF30A040B150BE80EF91E0A1F5A +:106850001B1F04C016950795F794E794DA94D2F7B6 +:10686000E986FA860B871C8725EFE2162FE0F206F1 +:1068700020E0020720E0120758F185EFE8168FEFBD +:10688000F80680E0080780E0180730F180914E3666 +:1068900090914F36A0915036B09151368A8F9B8F90 +:1068A000AC8FBD8F80E28F8B81E0F8CE6091463651 +:1068B0007091473680914836909149367ACF8091D1 +:1068C000423690914336A0914436B0914536B9CFC7 +:1068D0008CE08F8B80E0E2CE80E18F8B81E0DECE9A +:1068E000CF93DF93DC01CD91DC9111971C161D062F +:1068F000DCF41296E0E0F0E020E030E0A901542F53 +:10690000432F322F22276D9170E080E090E0262BFC +:10691000372B482B592B3196EC17FD0781F7B9011E +:10692000CA01DF91CF91089520E030E0A901F7CFAF +:10693000CF93DF93FB01DC012D913C91B9016E5F98 +:106940007F4FEC01C60FD71FE60FF71FD901119635 +:10695000A40FB51F2115310599F0215030408A91BF +:1069600092914115510519F06C9186239623119748 +:10697000891781F320E030E0C901DF91CF910895BC +:1069800021E030E0C901DF91CF910895CF93DF93EB +:10699000FB0120813181DC012D933C93A081B181E9 +:1069A000109701F1BD01615070401296EA0FFB1F74 +:1069B000EA01CA0FDB1FA80FB91F80E09A9122914C +:1069C00030E0290F311D280F311D81E02F3F3105A7 +:1069D00009F008F480E02E93615070409FEF6F3F04 +:1069E000790761F7DF91CF910895EF92FF920F93AE +:1069F0001F93CF93DF938B01FC017183608361153B +:106A0000710581F022E0E22EF12CE80EF91EC0E0C3 +:106A1000D0E0C7018C0F9D1F0E944D3D2196C017ED +:106A2000D107B9F7DF91CF911F910F91FF90EF90B0 +:106A3000089524E030E0FC013783268384E090E071 +:106A4000089521E0FC01208380E090E00895EF921A +:106A5000FF920F931F93DF93CF930F92CDB7DEB7C3 +:106A60007C018E010F5F1F4FC8010E944D3D89813F +:106A70008823D1F7F7011782168280E090E00F900B +:106A8000CF91DF911F910F91FF90EF9008950F9399 +:106A90001F93DF93CF930F92CDB7DEB78C01CE015A +:106AA0000196FBD78981823070F085E090E0F80193 +:106AB0009783868325E030E0C9010F90CF91DF9165 +:106AC0001F910F910895F8019181933141F088232E +:106AD00069F481E0F801828720E030E0EDCF88237F +:106AE00059F481E0818720E030E0E6CF86E0F801CC +:106AF000828720E030E0E0CF8DE0F801818720E060 +:106B000030E0DACF0B96C9D780E090E00895CF93BC +:106B1000DF93EC016C897D898E559F4F66DF6C8910 +:106B20007D89CE018B539F4F60DF80E090E0DF9145 +:106B3000CF910895FC016489758981589F4F55DF75 +:106B400080E090E008950F931F93CF93DF938C0123 +:106B5000EC016696CE0164E070E047DFCE01C0DE56 +:106B6000F801648775878687978780E090E0DF91DA +:106B7000CF911F910F9108950F931F93CF93DF93A0 +:106B80008C01EC016696CE0164E070E02EDFCE0150 +:106B9000A7DEF801608B718B828B938B695F7F4FCF +:106BA0008F4F9F4F28E030E040E050E00E94DE3DF4 +:106BB000F801358B248B2132310564F086E090E0BA +:106BC0009783868326E030E0C901DF91CF911F9142 +:106BD0000F91089520E030E0C901DF91CF911F911E +:106BE0000F910895BC0181E090E02BD780E090E008 +:106BF00060E070E026D780E090E061E070E021C7BF +:106C00004F925F926F927F928F929F92AF92BF92BC +:106C1000CF92DF92EF92FF920F931F93CF93DF9368 +:106C2000EC01F62E662309F4A4C08881861709F4C6 +:106C3000EEC06730C1F06E30C1F48D30B1F005E0C8 +:106C400010E0C801DF91CF911F910F91FF90EF905D +:106C5000DF90CF90BF90AF909F908F907F906F907C +:106C60005F904F900895863051F700E010E0A8E063 +:106C7000AA2EFCE0CF2EEEE06E2E7FE0B72E62E073 +:106C8000E62E992493945AE0752E45E0D42E37E0F1 +:106C9000832E23E0422E99E0592EF81691F2873088 +:106CA00009F495C08830A8F4833009F453C08430C7 +:106CB00008F03CC08130A1F1823008F454C08F2D1F +:106CC000893008F49EC081E090E08CDF5882888192 +:106CD000E4CF8B3059F08C3078F4893009F467C0F8 +:106CE0008A3008F47DC09F2D9B3089F081E090E0D0 +:106CF00079DFC8828881D1CF8D3009F452C08D30C0 +:106D000000F18E3009F075C09F2D9B30E9F480E0D2 +:106D100090E068DFF8828881C0CF8F2D813019F133 +:106D200081E090E05FDFE8828881B7CF853009F4A9 +:106D300044C0863090F081E090E054DF8882888102 +:106D4000ACCF8F2D8D3019F381E090E04BDFB8820E +:106D50008881A3CF9F2D9430D1F281E090E042DF73 +:106D6000D88288819ACF80E090E03CDF9882888149 +:106D700094CF81E090E036DF00E010E080E090E02A +:106D800060E070E05ED680E090E061E070E059D6AF +:106D90000F5F1F4F0530110589F7188200E010E0E2 +:106DA00050CF81E090E01EDF6882888176CF80E05E +:106DB00090E018DF7882888170CF8F2D863009F4BB +:106DC000A6CF81E090E00EDFA882888166CF9F2D5C +:106DD000943009F49CCF81E090E004DFA882F5CFE5 +:106DE0008F2D813009F493CF81E090E0FBDEE882C3 +:106DF0009BCF8F3009F491CFF88205E010E08881B5 +:106E00004CCF80E090E0EEDE4882888146CF86302D +:106E100049F08D3009F029CF81E090E0E3DE8EE08B +:106E2000888323CF81E090E0DDDE87E088831DCF7B +:106E3000CF92DF92EF92FF920F931F93CF93DF9346 +:106E4000EC018C010A5E1F4FC80161E070E0CDDDEE +:106E5000C88CC80161E070E0C8DDD88CC80164E06E +:106E600070E0C3DDC8013CDD7B018C0188858C1599 +:106E700021F0CE0108966C2DC3DEC801B70123D6E0 +:106E800088858D1521F0CE0108966D2DB9DE80E044 +:106E900090E0DF91CF911F910F91FF90EF90DF90E5 +:106EA000CF9008950F931F93DF93CF930F92CDB799 +:106EB000DEB78C01CE010196F0D5C8010896698134 +:106EC0009FDE9C01009719F0F80197838683C90122 +:106ED0000F90CF91DF911F910F9108954F925F9284 +:106EE0006F927F928F929F92AF92BF92CF92DF92DA +:106EF000EF92FF920F931F93CF93DF935B016C018F +:106F0000FA0138012115310509F481C08081918190 +:106F1000D90111969C938E93808191818C010E5F93 +:106F20001F4F020F131FA114B104C104D10409F4AF +:106F30005DC022E0422E512C480E591E4E0E5F1E9F +:106F40000CC00115110519F0D8019E928D01A114F4 +:106F5000B104C104D10409F449C0F20182902F01A7 +:106F6000EE24FF2499240894A108B108C108D1088F +:106F70006114710429F0A114B104C104D10481F198 +:106F8000C82DD0E0BE016170707082E090E059D5EC +:106F900080E090E060E070E054D50115110549F003 +:106FA0008ED590E00E2C02C0880F991F0A94E2F74C +:106FB000982A80E090E061E070E043D5A114B1042C +:106FC000C104D10409F4BDCF0894E11CF11CF8E020 +:106FD000EF16F10409F4B5CFD595C7958C2EC3CF24 +:106FE00081E090E061E070E02CD5CACFDF91CF91D5 +:106FF0001F910F91FF90EF90DF90CF90BF90AF90D7 +:107000009F908F907F906F905F904F9008958081B8 +:10701000918100E010E087CF2F923F924F925F92D4 +:107020006F927F928F929F92AF92BF92CF92DF9298 +:10703000EF92FF920F931F93DF93CF93CDB7DEB7FD +:1070400028970FB6F894DEBF0FBECDBF3C01962E39 +:1070500029833A834B835C831E830D8317012601AA +:10706000B886AF82A9A051E0C52ED12C681509F4CD +:1070700087C029813A814B815C8121153105410509 +:10708000510529F58D8D9E8DAF8DB8A10097A10575 +:10709000B10509F097C020E030E0C90128960FB68D +:1070A000F894DEBF0FBECDBFCF91DF911F910F913E +:1070B000FF90EF90DF90CF90BF90AF909F908F9018 +:1070C0007F906F905F904F903F902F900895BB24DA +:1070D000EE24FF24C301692D93DD69817A818B81C0 +:1070E0009C814D815E8191018601F8DE411451043D +:1070F00061F0C201B1014F8158851ADC41E0E42EF4 +:10710000F12C009711F0EE24FF24C114D104E9F012 +:10711000D3018C918F5F8C93E114F10459F02D8D84 +:107120003E8D4F8D58A1211531054105510511F0B6 +:10713000BA1448F1C301682D63DD8D8D9E8DAF8D2E +:10714000B8A10097A105B10591F4E114F10409F487 +:10715000A2CFB3948B2D81508A1508F4BBCFAA20FF +:1071600019F0AB1408F439C022E030E096CFC30127 +:1071700061E046DD6D8D7E8D8F8D98A1A4D4E5CF25 +:10718000CC24DD2476CFC30166E03ADDC30164E0A0 +:1071900037DD8D8D9E8DAF8DB8A1B595A79597954F +:1071A0008795B595A795979587952D8D3E8D4F8D94 +:1071B00058A1280F391F4A1F5B1F2D8F3E8F4F8FFD +:1071C00058A3BBCFC30161E01BDD6D8D7E8D8F8D1C +:1071D00098A179D420E030E060CF23E030E05DCFAB +:1071E0008F92AF92BF92CF92DF92EF92FF920F9366 +:1071F0001F93CF93DF93EC018C010A5E1F4F6C89C4 +:107200007D89C801F2DB00D000D00F92288939892E +:107210004A895B89ECE5EE2EF12CEC0EFD1E79E33C +:10722000C72ED12CCC0EDD1E6FE7A62EB12CAC0ED6 +:10723000BD1E8C859D85AE85BF85EDB7FEB781836C +:107240009283A383B4838B858583CE01089664E003 +:107250008A84E2DE9C010F900F900F900F900F90A8 +:10726000009711F09F838E83C901DF91CF911F9109 +:107270000F91FF90EF90DF90CF90BF90AF908F90E5 +:1072800008958F92AF92BF92CF92DF92EF92FF92CA +:107290000F931F93CF93DF93EC018C010A5E1F4F76 +:1072A000C80162E070E0A1DBC8011ADB6B017C0160 +:1072B000695F7F4F8F4F9F4F28E030E040E050E004 +:1072C0007DD4213231058CF026E030E03F832E83DF +:1072D000C901DF91CF911F910F91FF90EF90DF9047 +:1072E000CF90BF90AF908F900895C801B9017DDB1A +:1072F00000D000D00F928C859D85AE85BF85EDB7FF +:10730000FEB781839283A383B4831582CE0108964E +:107310006BE0A7019601EE24FF24CC24DD24AA24EF +:10732000BB24898479DE9C010F900F900F900F9001 +:107330000F90009769F2CACF6F927F928F92AF92AF +:10734000BF92CF92DF92EF92FF920F931F93DF9342 +:10735000CF930F92CDB7DEB73C01CE0101969DD3FE +:1073600083010A5E1F4F298130E040E050E0295F31 +:107370003F4F4F4F5F4FF3E0559547953795279512 +:10738000FA95D1F7C801B90130DB00D000D00F92D7 +:10739000298130E040E050E0F30184859585A685A1 +:1073A000B785EDB7FEB781839283A383B48315823B +:1073B000C30108966BE0EE24FF24CC24DD24AA242C +:1073C000BB24F301818428DE9C010F900F900F9065 +:1073D0000F900F90009719F0F30197838683C901EE +:1073E0000F90CF91DF911F910F91FF90EF90DF9061 +:1073F000CF90BF90AF908F907F906F9008952F9215 +:107400003F924F925F926F927F928F92AF92BF9214 +:10741000CF92DF92EF92FF920F931F93DF93CF9360 +:1074200000D0CDB7DEB79A8389831A012B013901C9 +:10743000C801B901DADAC114D10419F0C601B301E7 +:10744000D4DA00D000D00F928E899F89A88DB98D93 +:10745000EDB7FEB781839283A383B4838A8D85833E +:1074600089819A8164E0A2019101D6DD0F900F908D +:107470000F900F900F900F900F90CF91DF911F9171 +:107480000F91FF90EF90DF90CF90BF90AF908F90D3 +:107490007F906F905F904F903F902F9008958F92C4 +:1074A000AF92BF92CF92DF92EF92FF920F931F9312 +:1074B000CF93DF93EC0189818131D9F114E0812EE2 +:1074C00000D000D00F92488959896A897B892C891C +:1074D0003D898E010A5E1F4FBCE5EB2EF12CEC0EB0 +:1074E000FD1EA9E3CA2ED12CCC0EDD1EEDB7FEB7D2 +:1074F00011821282138214821582CE010896AA2468 +:10750000BB247DDF9C010F900F900F900F900F9088 +:10751000009711F09F838E83C901DF91CF911F9156 +:107520000F91FF90EF90DF90CF90BF90AF908F9032 +:1075300008958A84C5CF8F92AF92BF92CF92DF9287 +:10754000EF92FF920F931F93CF93DF93EC0189810A +:107550008E30A9F104E0802E00D000D00F9248892F +:1075600059896A897B892C893D898E010A5E1F4F62 +:10757000EDB7FEB711821282138214821582CE01FA +:107580000896EE24FF24CC24DD24AA24BB2437DF74 +:107590009C010F900F900F900F900F90009711F09B +:1075A0009F838E83C901DF91CF911F910F91FF902F +:1075B000EF90DF90CF90BF90AF908F9008958A8426 +:1075C000CBCF8F92AF92BF92CF92DF92EF92FF928A +:1075D0000F931F93CF93DF93EC0100D000D00F9255 +:1075E000488959896A897B892C893D898C010A5E81 +:1075F0001F4FECE5EE2EF12CE80EF91E99E3C92E93 +:10760000D12CCC0EDD1E8FE7A82EB12CAC0EBD1EEA +:107610008C859D85AE85BF85EDB7FEB7818392834E +:10762000A383B4838B858583CE0108968A84E7DEA5 +:107630009C010F900F900F900F900F90009711F0FA +:107640009F838E83C901DF91CF911F910F91FF908E +:10765000EF90DF90CF90BF90AF908F900895CF9232 +:10766000DF92EF92FF920F931F93CF93DF938C01E2 +:107670006B017901B8018AD9E60128813981F701C6 +:10768000A081B181AD014150504057FD38C0FD018E +:107690003296EE0DFF1D1196A00FB11F60E010E0B5 +:1076A0008291882329F1EC9001E00AC0762F660FC1 +:1076B0007123B1F0E02A959587958823C1F0000FDA +:1076C00090E080FFF8CF662389F721503040B60163 +:1076D000620F731FEB011A8162E071E0712351F7B1 +:1076E000702F7095E72295958795882341F7EC9246 +:1076F0004150504011978FEF4F3F580789F6DF9167 +:10770000CF911F910F91FF90EF90DF90CF90089550 +:107710002F923F924F925F926F927F928F929F92A1 +:10772000AF92BF92CF92DF92EF92FF920F931F938F +:10773000DF93CF93CDB7DEB761970FB6F894DEBF76 +:107740000FBECDBF3C01B6E14B2E512C480E591E49 +:10775000FC0164897589C20148D9C30108969D83DB +:107760008C83F301E45AFF4FFF83EE83C301C99674 +:1077700099878887AFE72A2E312C260C371C00D03A +:1077800000D00F92F3012089318942895389848581 +:107790009585A685B785EDB7FEB781839283A383D0 +:1077A000B483F3018385EDB7FEB785838C819D811A +:1077B00064E08201EE80FF80C884D9845101F30126 +:1077C00082842ADC9B838A830F900F900F900F9006 +:1077D0000F90009709F087C0C3018B539F4F9D877F +:1077E0008C87FC0140815181141615060CF09DC058 +:1077F000E0E0F0E060E000E010E0E60DF71DE953A6 +:10780000FF4F8081882351F090E09C0121703070FF +:10781000020F131F959587958823B1F76F5FE62FA9 +:10782000F0E0E417F5074CF3CE01019636D122279C +:1078300017FD2095322F095F1F4F2F4F3F4FE3E079 +:107840003595279517950795EA95D1F71F870E87E8 +:107850009924C30188519F4F9B878A87F301EE5576 +:10786000FF4FF98BE88B8981981608F043C08A8511 +:107870009B856E857F85B9D8C2016A857B854889DD +:1078800059892C853D85EBDE00D000D00F92F301A5 +:10789000208931894289538984859585A685B78554 +:1078A000EDB7FEB781839283A383B483F30183850D +:1078B000EDB7FEB785838C819D8164E08201EE8007 +:1078C000FF80C884D9845101F3018284A5DB0F9025 +:1078D0000F900F900F900F90009739F49394898137 +:1078E000981640F4C4CF8A819B81F30197838683E5 +:1078F0009B838A838A819B8161960FB6F894DEBF51 +:107900000FBECDBFCF91DF911F910F91FF90EF90F0 +:10791000DF90CF90BF90AF909F908F907F906F90AF +:107920005F904F903F902F90089500E010E07CCF43 +:10793000CF93DF93EC01188219821A821B821C827A +:107940001D821F821E821B86188681E089878A8796 +:10795000188A198A1A8A1B8A1D8A1C8A1C861D8607 +:107960001E861F86CE01089660E04AD98E839F83CB +:10797000DF91CF910895CF93DF93EC012E813F816A +:107980002115310519F48881882321F0C901DF917F +:10799000CF910895CE01019680D08A819B81AC81E0 +:1079A000BD810196A11DB11D8A839B83AC83BD83DC +:1079B000E981E83150F084E090E09F838E8324E0F9 +:1079C00030E0C901DF91CF910895F0E0EE0FFF1F85 +:1079D000EA5CFC4F0190F081E02DCE0109952E81EB +:1079E0003F81D4CF0F931F93DF93CF93CDB7DEB7F3 +:1079F000CB50D1400FB6F894DEBF0FBECDBF8E0185 +:107A00000F5F1F4FC80194DF2F8138852115310585 +:107A100069F0C901C55FDE4F0FB6F894DEBF0FBE37 +:107A2000CDBFCF91DF911F910F9108958981882358 +:107A300081F7C801A0DF2F81388521153105B1F309 +:107A4000E8CF8130910551F08230910561F00097C7 +:107A500021F46115710571F442980895611571055D +:107A600039F0439A08956115710531F0459A0895EA +:107A700043980895429A08954598089580E090E0CB +:107A800060E070E0DEDF80E090E061E070E0D9CFA0 +:107A900090932A38809329380895CF93DF93EC018F +:107AA000E0912938F0912A38309729F00995888398 +:107AB000DF91CF9108951882DF91CF91089581E0F1 +:107AC000349B80E00895AF92BF92CF92DF92EF9205 +:107AD000FF920F931F935B016C0116161706180691 +:107AE000190674F4EE24FF248701C8DF0894E11C12 +:107AF000F11C011D111DEA14FB040C051D05ACF35E +:107B00001F910F91FF90EF90DF90CF90BF90AF90BB +:107B10000895629FD001739FF001829FE00DF11DD7 +:107B2000649FE00DF11D929FF00D839FF00D749FF7 +:107B3000F00D659FF00D9927729FB00DE11DF91FA3 +:107B4000639FB00DE11DF91FBD01CF011124089500 +:107B5000AA1BBB1B51E107C0AA1FBB1FA617B70773 +:107B600010F0A61BB70B881F991F5A95A9F780958F +:107B70009095BC01CD010895A1E21A2EAA1BBB1B52 +:107B8000FD010DC0AA1FBB1FEE1FFF1FA217B307E9 +:107B9000E407F50720F0A21BB30BE40BF50B661FFF +:107BA000771F881F991F1A9469F7609570958095C3 +:107BB00090959B01AC01BD01CF01089597FB092E63 +:107BC00005260ED057FD04D0D7DF0AD0001C38F4AC +:107BD00050954095309521953F4F4F4F5F4F0895F9 +:107BE000F6F790958095709561957F4F8F4F9F4FD9 +:107BF00008950790F691E02D09949111089581560A +:107C00008A5108F4805285580895FB01DC010590E3 +:107C10000D920020E1F70895FC0105900020E9F79E +:107C2000809590958E0F9F1F0895FB01DC0104C085 +:107C30008D910190801921F441505040C8F7881B64 +:107C4000990B0895FB01DC0102C001900D92415097 +:107C50005040D8F70895FB01DC014150504030F00E +:107C60008D910190801919F40020B9F7881B990BA8 +:107C70000895FB01DC014150504048F001900D9205 +:107C80000020C9F701C01D9241505040E0F708950F +:107C90000F931F93DF93CF93CDB7DEB72E970FB619 +:107CA000F894DEBF0FBECDBF0D891E898F89988DD8 +:107CB00026E02C831A83098397FF02C080E090E8B6 +:107CC00001979E838D839E01255E3F4FCE010196D5 +:107CD000698D7A8DA90119D04D815E8157FD0AC049 +:107CE0002F813885421753070CF49A01020F131F96 +:107CF000F80110822E960FB6F894DEBF0FBECDBFEE +:107D0000CF91DF911F910F9108952F923F924F9243 +:107D10005F926F927F928F929F92AF92BF92CF921B +:107D2000DF92EF92FF920F931F93DF93CF93CDB724 +:107D3000DEB72C970FB6F894DEBF0FBECDBF6C0137 +:107D40001B018A01FC0117821682838181FFC4C155 +:107D50002E010894411C511CF6019381F10193FD01 +:107D6000859193FF81911F01882309F4B1C1853268 +:107D700039F493FD859193FF81911F01853221F4A0 +:107D800090E0B601F5D1E8CFEE24FF2420E02032C8 +:107D9000B0F48B3269F08C3228F4803251F08332A7 +:107DA00071F40BC08D3239F0803349F421602CC05E +:107DB0002260246029C0286027C0206125C027FDDB +:107DC0002CC0382F30533A3098F426FF08C08E2D3F +:107DD000880FE82EEE0CEE0CE80EE30E15C08F2D8A +:107DE000880FF82EFF0CFF0CF80EF30E20620CC06B +:107DF0008E3221F426FD6CC1206406C08C3611F44D +:107E0000206802C0883649F4F10193FD859193FF03 +:107E100081911F01882309F0BACF982F9554933090 +:107E200018F09052933028F40C5F1F4FFFE3F98352 +:107E30000DC0833631F0833771F0833509F05CC0B3 +:107E400021C0F801808189830E5F1F4F420171E0DC +:107E5000A72EB12C15C062E0662E712C600E711E2B +:107E6000F8018080918026FF03C06E2D70E002C073 +:107E70006FEF7FEFC4012C8770D15C0183012C85EB +:107E80002F7716C052E0652E712C600E711EF8011E +:107E90008080918026FF03C06E2D70E002C06FEFDE +:107EA0007FEFC4012C874ED15C012C8520688301B3 +:107EB00023FD1EC007C080E290E0B6012C8758D198 +:107EC000FA942C858F2D90E0A816B906A0F310C067 +:107ED000F40127FD859127FF81914F0190E0B601C4 +:107EE0002C8746D12C85F110FA940894A108B1088A +:107EF000A114B10469F7E9C0843611F0893641F55F +:107F000027FF08C0F80160817181828193810C5F35 +:107F10001F4F09C0F80160817181882777FD809526 +:107F2000982F0E5F1F4F4FE6B42EB22297FF09C065 +:107F300090958095709561957F4F8F4F9F4FF0E89A +:107F4000BF2AA2012AE030E03FD1782E741844C045 +:107F5000853731F43FEEB32EB2222AE030E025C05F +:107F600099EFB92EB2228F36C1F0803720F48835D0 +:107F700009F0AEC00DC0803721F0883709F0A8C0E5 +:107F800002C020E1B22AB4FE0BC084E0B82A08C0C7 +:107F9000B4FE09C0E6E0BE2A06C028E030E005C015 +:107FA00020E130E002C020E132E0B7FE08C0F80175 +:107FB00060817181828193810C5F1F4F07C0F8013E +:107FC0006081718180E090E00E5F1F4FA201FCD0C4 +:107FD000782E7418FFE7BF22B6FE0BC02EEFB22238 +:107FE0007E1438F4B4FE07C0B2FC05C08FEEB82290 +:107FF00002C0A72C01C0AE2C8B2D90E0B4FE0DC0AA +:10800000FE01E70DF11D2081203319F4E9EEBE22B7 +:1080100009C0A394B2FE06C004C086789070009791 +:1080200009F0A3948B2C9924B3FC13C0B0FE0EC0AE +:10803000AF1428F4E72CEF0CEA18AF2C07C0E72C9C +:1080400005C080E290E0B60193D0A394AF14C8F3CA +:1080500004C0AF1410F4FA1801C0FF2484FE0EC04F +:1080600080E390E0B60184D082FE1DC081FE03C093 +:1080700088E590E010C088E790E00DC0C4018678E4 +:108080009070009781F081FC02C080E201C08BE219 +:10809000B7FC8DE290E0B6016BD005C080E390E0C4 +:1080A000B60166D0EA947E14C8F37A94F201E70D23 +:1080B000F11D808190E0B6015BD07720B1F705C05B +:1080C00080E290E0B60154D0FA94FF20C9F744CE84 +:1080D000F6012681378102C02FEF3FEFC9012C96B0 +:1080E0000FB6F894DEBF0FBECDBFCF91DF911F91C9 +:1080F0000F91FF90EF90DF90CF90BF90AF909F9047 +:108100008F907F906F905F904F903F902F90089549 +:10811000F999FECF92BD81BDF89A992780B508954F +:10812000262FF999FECF92BD81BDF89A019700B430 +:10813000021639F01FBA20BD0FB6F894FA9AF99AD0 +:108140000FBE0895FC010590615070400110D8F7F2 +:10815000809590958E0F9F1F0895FC01615070408F +:1081600001900110D8F7809590958E0F9F1F08956C +:108170000F931F93CF93DF938C01EB018B8181FFD2 +:108180001BC082FF0DC02E813F818C819D812817ED +:10819000390764F4E881F9810193F983E88306C023 +:1081A000E885F985802F0995009731F48E819F81AC +:1081B00001969F838E8302C00FEF1FEFC801DF91EE +:1081C000CF911F910F910895FA01AA27283051F1FC +:1081D000203181F1E8946F936E7F6E5F7F4F8F4FF8 +:1081E0009F4FAF4FB1E03ED0B4E03CD0670F781F57 +:1081F000891F9A1FA11D680F791F8A1F911DA11D3C +:108200006A0F711D811D911DA11D20D009F4689474 +:108210003F912AE0269F11243019305D3193DEF61C +:10822000CF010895462F4770405D4193B3E00FD0D2 +:10823000C9F7F6CF462F4F70405D4A3318F0495DBD +:1082400031FD4052419302D0A9F7EACFB4E0A695A0 +:108250009795879577956795BA95C9F700976105C2 +:10826000710508959B01AC010A2E06945795479518 +:1082700037952795BA95C9F7620F731F841F951F0D +:10828000A01D089518E000E0C8E9D8E040E005C06E +:1082900022974109FE014BBFACDCCA39D107400728 +:0682A000B9F7F894FFCFCE +:1082A6002E2E0053656C656374204469736B006EF3 +:1082B6006F20696D6167652066696C657320666FFE +:1082C600756E640001030507090E10121416181CBA +:1082D6001E696E636F6D706C657465207772697464 +:1082E600650062616420736563746F722025642083 +:1082F600666F722074256400627566206C6F636B0E +:1083060065642025642F25643A25640063686563E7 +:108316006B73756D206661696C75726520300063DC +:108326006865636B73756D206661696C757265202F +:108336003100636865636B73756D206661696C7582 +:108346007265203200636865636B73756D206661C4 +:10835600696C006669726D776172652E7876660063 +:10836600524553554C543A205355434345535300B5 +:108376004649524D57415245204552524F522025AB +:10838600640043504C44204669726D7761726520E3 +:1083960025640025640025750053442072656164D8 +:1083A600206572726F722052004241442046555336 +:1083B600455320253032582025303258202530327A +:1083C600580043504C4420495320424C414E4B00E8 +:1083D60057524F4E472043504C44202D20256400D1 +:1083E60053454C462D54455354204F4B005344207F +:1083F60072656164207374617274206572726F7243 +:108406000053442072656164206572726F72204465 +:108416000077722077726F6E6720747261636B20CB +:1084260025642F2564005265766572746564207430 +:10843600726B202530326420202000534420726560 +:108446006164206572726F72205700534420777200 +:108456006974655374617274206661696C00534473 +:10846600207772697465206572726F7200534420BA +:10847600777269746553746F70206661696C005316 +:10848600617665642074726B202530326420696ED3 +:1084960020256C752020004E4F2053442043415226 +:1084A600443F0043415244204552524F52202564D6 +:1084B6003A256400253032640025642000D5AAAD33 +:1084C6000000000000000000000000008A01AD016D +:1084D600D8010D024E0221359A359C39F038A33564 +:1084E600193519358235BC35E13A8735883B9B3AD3 +:1084F6009B3A9B3A4F3A4F3A4F3A523747354735B0 +:068506004139273518374A +:020000021000EC +:08EFF800DDDDDDDD000100009C +:00000001FF diff --git a/floppy-emu-1.0Q-F13/merged.hex b/floppy-emu-1.0Q-F13/merged.hex new file mode 100755 index 0000000..43ab316 --- /dev/null +++ b/floppy-emu-1.0Q-F13/merged.hex @@ -0,0 +1,1198 @@ +:020000040000FA +:200000004CC4000079C4000077C4000075C400000C94990F71C400000C94250C0C94710BB5 +:200020006BC4000069C4000067C4000065C4000063C4000061C400005FC400005DC4000080 +:200040005BC4000059C400000C94F72155C4000053C4000051C400004FC400004DC4000043 +:200060004BC4000049C4000047C4000045C4000043C4000041C400003FC400003DC4000040 +:200080003BC4000039C4000037C4000000000C001800240030003C004800540060006C004D +:2000A0007800840090009C00A800B400C000CB00D600E100EC00F70002010D011801230149 +:2000C0002E01390144014F015A01650170017A0184018E019801A201AC01B601C001CA0135 +:2000E000D401DE01E801F201FC0106021002190222022B0234023D0246024F025802610222 +:200100006A0273027C0285028E029702A002A802B002B802C002C802D002D802E002E80214 +:20012000F002F80200030803100318030C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0B0B0B0BAB +:200140000B0B0B0B0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0909090957 +:200160000909090909090909090909090808080808080808080808080808080896979A9B31 +:200180009D9E9FA6A7ABACADAEAFB2B3B4B5B6B7B9BABBBCBDBEBFCBCDCECFD3D6D7D9DA10 +:2001A000DBDCDDDEDFE5E6E7E9EAEBECEDEEEFF2F3F4F5F6F7F9FAFBFCFDFEFF0001FFFF2A +:2001C0000203FF040506FFFFFFFFFFFF0708FFFFFF090A0B0C0DFFFF0E0F10111213FF145B +:2001E00015161718191AFFFFFFFFFFFFFFFFFFFFFF1BFF1C1D1EFFFFFF1FFFFF2021FF2290 +:20020000232425262728FFFFFFFFFF292A2BFF2C2D2E2F303132FFFF333435363738FF39C5 +:200220003A3B3C3D3E3F00002110422063308440A550C660E770088129914AA16BB18CC160 +:20024000ADD1CEE1EFF13112100273325222B5529442F772D662399318837BB35AA3BDD383 +:200260009CC3FFF3DEE36224433420040114E664C774A44485546AA54BB528850995EEE5C3 +:20028000CFF5ACC58DD55336722611163006D776F6669556B4465BB77AA719973887DFF743 +:2002A000FEE79DD7BCC7C448E5588668A7784008611802282338CCC9EDD98EE9AFF948897B +:2002C00069990AA92BB9F55AD44AB77A966A711A500A333A122AFDDBDCCBBFFB9EEB799B83 +:2002E000588B3BBB1AABA66C877CE44CC55C222C033C600C411CAEED8FFDECCDCDDD2AAD43 +:200300000BBD688D499D977EB66ED55EF44E133E322E511E700E9FFFBEEFDDDFFCCF1BBF42 +:200320003AAF599F788F8891A981CAB1EBA10CD12DC14EF16FE18010A100C230E3200450B7 +:20034000254046706760B9839893FBA3DAB33DC31CD37FE35EF3B1029012F322D2323542A2 +:20036000145277625672EAB5CBA5A89589856EF54FE52CD50DC5E234C324A01481046674A2 +:20038000476424540544DBA7FAB79987B8975FE77EF71DC73CD7D326F2369106B016576662 +:2003A0007676154634564CD96DC90EF92FE9C899E9898AB9ABA94458654806782768C0185A +:2003C000E1088238A3287DCB5CDB3FEB1EFBF98BD89BBBAB9ABB754A545A376A167AF10AA2 +:2003E000D01AB32A923A2EFD0FED6CDD4DCDAABD8BADE89DC98D267C076C645C454CA23C22 +:20040000832CE01CC10C1FEF3EFF5DCF7CDF9BAFBABFD98FF89F176E367E554E745E932E61 +:20042000B23ED10EF01E787C3C1E1E1E1E1E3E3EFEFCFCF8F0E0800000000000000000005F +:2004400080E0FFFFFFFF7F1F00000000FFFFFFFFFF07070303010100000000000078FCFC21 +:20046000FCFC7800000000000000000000C0201008080402020201010101F00E01000000FF +:20048000000000607070000000000F708000000000008040201010080808000000030408F6 +:2004A000101020404040808080800F70800000000000081020404080808020202020202045 +:2004C000202020202020202020202020202020002049646C6500205265616400577269745C +:2004E0006500547261636B202020205369646500313434304B204469736B436F70792069BA +:200500006D616765003830304B204469736B436F707920696D616765003430304B20446949 +:20052000736B436F707920696D61676500313434304B2072617720696D61676500383030E6 +:200540004B2072617720696D616765003430304B2072617720696D61676500696D61676554 +:20056000206E6F7420636F6E746967756F7573006572726F72206F70656E696E6720696D6A +:2005800061676500504C454153452057414954003130313031303130313031302E2E2E004F +:2005A00030313031303130313031303130313000202020205550444154494E472043504C89 +:2005C000442020202000436F6E74726173743A200053454C4543543A2053617665004E4573 +:2005E00058543A204461726B657200505245563A204C69676874657200626567696E0052DF +:20060000656C6561736520627574746F6E7320746F00434F4E54524153542041444A555334 +:20062000544D454E54004170702056657273696F6E20312E302051002020202020464C4F6A +:2006400050505920454D552020202020200053442052454144204552524F5220520066691C +:20066000726D776172652E78766600436F756C64206E6F74206F70656E00434845434B20B2 +:2006800050494E53202D2044454641554C5400434845434B2050494E20434C4B4F2D48008B +:2006A000434845434B2050494E20434C4B4F2D4C00434845434B2050494E2052455345540B +:2006C00000434845434B2050494E20454A45435400434845434B2050494E20435552525F0A +:2006E0005349444500434845434B2050494E2052445F41434B00434845434B2050494E2007 +:200700005752455100434845434B2050494E20535445505F52455100434845434B2050497B +:200720004E20535445505F44495200434845434B2050494E53202D20414C4C0046415441B7 +:200740004C204552524F5220202020202020202020005752495445204552524F52202020CE +:2007600020202020202020000000000017000300031F0A1F0A1F050904120F171C0003039F +:20078000000E11110E00050205040E041008000404040010001804031E110F021F00191519 +:2007A0001215150A07041F1715091E151D1905031A150B17150F000A00040C04040E1F0A55 +:2007C0000A0A1F0E040115030E15161E051E1F150A0E11111F110E1F15151F05050E151DE3 +:2007E0001F041F111F1108100F1F041B1F10101F061F1F0E1F0E110E1F05020E191E1F0D7E +:2008000016121509011F010F101F0718071F0C1F1B041B031C031915131F101002040810C9 +:20082000101F0406041010100003031A161C1F120C0C12120C121F0C1A16041E050C2A1E98 +:200840001F021C001D0010201D1F0C12111F101E0E1E1E021C0C120C3E120C0C123E1C02EE +:2008600002141E0A021F120E101E0E180E1E1C1E120C1206281E1A1F16041B11001F001114 +:200880001B04080C047C3C3E5E2B3D3F2F5B5D3B2C2A225C0000E221E62111241FBECFEF56 +:2008A000D0E4DEBFCDBF13E0A0E0B1E0E6EAF2E800E00BBF02C007900D92A636B107D9F7A7 +:2008C00018E3A6E6B3E001C01D92AB32B107E1F718E000E0C8E9D8E040E006C022974109F7 +:2008E000FE014BBF0E94F93DC639D1074007B1F70E94791C0C94424183CB2F923F924F9236 +:200900005F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB760 +:20092000DEB72D970FB6F894DEBF0FBECDBF8B014A013E010894611C711CD301E4E2F1E0F0 +:200940002DE001900D922150E1F7BB244424AA2452E8552E42E2E42EF12CE80EF91E3EE0C1 +:20096000C32ED12CCC0EDD1E22E8222E312C280C391CC701B80140E250E00E9448298032DC +:200980009105A1F4D8011B968C911B9790E09C012F7330702F30310559F183FD23C0F80149 +:2009A0008081853E19F1882309F05AC0D4011C9280E02D960FB6F894DEBF0FBECDBFCF915E +:2009C000DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F90F4 +:2009E0002F900895F8018081882301F3BB24C1CFBB2021F58C91982F907E903409F0B9CF6B +:200A00009FE1A92EA8221D964C90F1011082A5E7B0E085E7582EF301AD01480D591D819115 +:200A20009801280F311DD9018C91DA018D93AD01EC15FD05A1F7BB24B3949BCFD8018C91D7 +:200A4000AA948A1599F61D968C911D97841571F6552009F48ECFB3EF5B0EA52DB0E0DBCFC0 +:200A60008E3221F2BB2081F031962BE090E001C08191392F3795332737959695932B980F58 +:200A80002150B1F7941531F0C801B4010E94882881E08FCFFA2DF130B9F7452D50E04338CF +:200AA0005105B4F79A0160E080E090E0880D991D280D391DD9012C91FC0120836F5F862FFA +:200AC00090E09C01240F351F233831057CF381E070CFEF92FF920F931F93DF93CF93CDB724 +:200AE000DEB7A9970FB6F894DEBF0FBECDBFFC01DB018C918E32A9F1838590E08871907019 +:200B00008031910509F466C0009759F5848D958DA68DB78D803020E4920726E0A20720E0E0 +:200B2000B20709F459C0803020E892072CE0A20720E0B20709F454C0803020E8920726E1BE +:200B4000A20720E0B20709F449C081509044A640B0408F3F2FE2920721E1A20720E0B207D6 +:200B600078F020E0822FA9960FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF9008950B +:200B8000CF017E010894E11CF11CB7010E9488281E86198A8E01025F1F4FC801B70141E00F +:200BA0000E94B32E882371F0C80163EC73E340E052E00E944829C8010E94B22B8091153431 +:200BC000813081F08989882361F2C8010E94B22B20E0C8CF21E0C6CF23E0C4CF25E0C2CF42 +:200BE00024E0C0CF80911634882361F78091043490E0A0E0B0E0BA2FA92F982F8827209153 +:200C00000534820F911DA11DB11DB695A79597958795B695A79597958795803921E09207DF +:200C200020E0A20720E0B207F1F0803223E0920720E0A20720E0B207A1F0803A25E09207D8 +:200C400020E0A20720E0B20709F0BCCF28E08989882309F487CFC80129A70E94B22B29A5B0 +:200C600081CF27E0F4CF26E0F2CF2F923F924F925F926F927F928F929F92AF92BF92CF92D8 +:200C8000DF92EF92FF920F931F93DF93CF93CDB7DEB7C05FD0400FB6F894DEBF0FBECDBF1A +:200CA0007C011092670310926603829640E050E0BA010E94CA2A03E4C02ED12CCC0EDD1E40 +:200CC00013E6A12EB12CAC0EBD1EB4E26B2E712CC701B601A50111DE8823E1F18091660303 +:200CE0009091670321E08734920708F0A7C1C601B501EFDE882E882359F380916603909122 +:200D00006703869D8001879D100D969D100D11240D531C4FC801B50146E150E00E94393E45 +:200D2000B8016A5E7F4FC6010E9488288091660390916703869DF001879DF00D969DF00DE1 +:200D40001124ED53FC4F83A201969093670380936603BECF2091660330916703C751DF4FF6 +:200D600039832883C95ED040F70185A182508230A8F184E290E0C751DF4FE881F981C95E74 +:200D8000D040E89F8001E99F100DF89F100D11240D531C4FC80160E071E046E150E00E948F +:200DA000393EC801469660E071E04DE050E00E94393E82E0F80183A3C751DF4F28813981E6 +:200DC000C95ED0402F5F3F4FC751DF4F39832883C95ED0403093670320936603A6EE2A2EA7 +:200DE000A3E03A2E80E090E07E010894E11CF11CF7E1CF2ED12CCC0EDD1EC751DF4FE881BD +:200E0000F981C95ED0408E179F0708F01EC1FC013196C351DF4FF983E883CD5ED040C751BF +:200E2000DF4F28813981C95ED040E217F30708F026C1C1018397F101B496C151DF4FF98344 +:200E4000E883CF5ED0405F01C351DF4F48805980CD5ED040CA51DF4F8883C65ED040910152 +:200E60002D503040C551DF4F39832883CB5ED040C951DF4F39822882C75ED040392EC70190 +:200E8000CA51DF4F6881C65ED040732D46E150E00E94393E88240AC00E0D1F1DF801808115 +:200EA00090E00E94FD3DF80180838394F70101900020E9F73197EE19FF09082D10E00E1729 +:200EC0001F0750F3EDED8E2EEFEF9E2E8A0C9B1C682C292CC601B40146E150E00E94393E47 +:200EE00077240AC00C0D1D1DF801808190E00E94FD3DF80180837394F60101900020E9F769 +:200F00003197EC19FD09072D10E00E171F0750F3C701B60146E150E00E942B3E282F392FAC +:200F2000C951DF4FE881F981C75ED04080818150823008F480C0F50180818150823008F41B +:200F400077C0121613060CF055C0CE018D96CA51DF4F6881C65ED040732D46E150E00E9417 +:200F6000393ECA51DF4F8881C65ED040932D662D722D46E150E00E94393E862D922DBE01E1 +:200F8000635D7F4F46E150E00E94393ECE018D96C551DF4F68817981CB5ED0404DE050E0A4 +:200FA0000E94393E84010A5E1F4FC551DF4F88819981CB5ED040B8014DE050E00E94393EEE +:200FC000C801BE01635D7F4F4DE050E00E94393EC951DF4FE881F981C75ED0408081F5012E +:200FE0009081C951DF4FE881F981C75ED0409083F50180830894411C511C24E230E0A20E48 +:20100000B31EC751DF4F88819981C95ED0404816590608F434CFC151DF4F28803980CF5ED5 +:20102000D040C351DF4F88819981CD5ED040E5CE28513C4F86CF285E33407DCFC751DF4F69 +:2010400099838883C95ED0408FCEC051DF4F0FB6F894DEBF0FBECDBFCF91DF911F910F912F +:20106000FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F902F900895C101EF +:201080008496C151DF4F99838883CF5ED040C3CF8F929F92AF92BF92CF92DF92EF92FF9238 +:2010A0000F931F93CF93DF93809168039091690320916A0330916B032817390728F4309354 +:2010C000690320936803C90104968217930730F424503040309369032093680380E060E0FA +:2010E0000E94372281E06FE70E942822C3E1D0E081E060E40E9428222197D1F783E091E019 +:201100000E942C23C3E1D0E081E060E40E9428222197D1F781E06FE70E94282220916603BC +:20112000309167032115310509F464C14091680350916903CA0105964817590708F033C15C +:201140004217530708F02FC164E270E0469F7001479FF00C569FF00C112486EE93E0E80E23 +:20116000F91EEA0191E0C92ED12CBB24B39480916A0390916B03C817D90709F0BB24AC2C66 +:2011800080E06C2D0E94372204E510E007C060E081E00E9428220150104049F0BB20B9F3CD +:2011A0006FE781E00E94282201501040B9F781E06A2D0E943722870103521040902E812EAE +:2011C000C8016B2D43E50E944322F70180818150823008F4BDC0BB2009F0A4C08601219614 +:2011E0004091680350916903CA010596C817D907E0F120916603309167032630310508F0A7 +:2012000047C0EE24E39482E56E2D0E94372281E060E00E94282281E060E00E942822E394B0 +:201220007E2D763081F780916803909169039801280F391F40916A0350916B034217530774 +:2012400008F4E2C02150304030936B0320936A030430110509F02CCF009709F429CF01975C +:20126000909369038093680323CF20916603309167030894C11CD11C64E270E0E60EF71E25 +:20128000C217D30708F471CF2630310508F4B9CFE7E2F0E04E9FC0014F9F900D5E9F900DE3 +:2012A00011248D539F4FB9010E94A83D88E0E82EE60E83EC90E0B9010E94A83DCE2CC61A7E +:2012C000C8E0D0E0BB24B39482E56B2D0E94372281E060E00E9428224C2F9E01295F3F4FD9 +:2012E0002C173D070CF484C060E00AC0E41650F0669560684F5F842F90E0281739074CF090 +:201300004C15A0F766954F5F842F90E028173907BCF781E00E942822B39428967B2D763037 +:2013200099F681CF82E893E0692D782D46E150E00E94393EB8016A5E7F4F8CE693E04DE0E5 +:2013400050E00E94393EF70180818093980346CF89E46A2D0E943722BB2041F181E06FE7C5 +:201360000E94282281E063E40E94282281E06DE50E94282281E06DE50E94282281E06DE5FC +:201380000E94282281E06BE50E94282281E06BE50E94282281E063E40E9428226FE781E0DC +:2013A0000E94282218CF00E010E027CF81E060E00E94282281E06CE30E94282281E062E2C6 +:2013C0000E94282281E062E20E94282281E062E20E94282281E064E20E94282281E064E2C5 +:2013E0000E94282281E06CE30E94282260E0D7CF60E08FCF80E061E00E9437228FE091E065 +:2014000060E044E50E944322DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F9084 +:2014200008958130910559F0009721F48091EF35882309F408958CEE95E30C94B22B109248 +:20144000EC351092EF350895DF92EF92FF920F931F93CF93DF93082F2B9882E282B95D98CF +:20146000429A289A45980E947B23CDEAD3E0FE0101900020E9F73197EC1BFD0B8E2F81950D +:20148000880F865D65E00E943722CE0160E044E50E9443220E94F021002309F438C00AE698 +:2014A00014E0DD2480E06D2D0E9437222AE1E22E81E060E00E942822EA94D1F790E1E92ECC +:2014C000F12CE00EF11EE801FE01649181E00E9428222196EC16FD06B9F7E8012F9601505D +:2014E0001040FE01649181E00E94282221970C171D07B9F70AE181E060E00E9428220150E3 +:20150000D1F7D394FD2DF43051F18701CBCFC6E2D4E0FF2480E06F2D0E94372201E281E030 +:2015200060E00E9428220150D1F78E010F5E1F4FFE01649181E00E94282221960C171D07BD +:20154000B9F782E2E82E81E060E00E942822EA94D1F7F394FF2DF43011F0E801DBCF98E0AB +:201560002FEB37E249E0215030404040E1F700C0000085B1892785B9F3CFEF920F9336B126 +:2015800091E0811190E0331F3327331F931759F0E9B1E095E170F0E081E090E0662339F430 +:2015A000E817F90749F080E00F91EF90089580E090E0E817F907B9F766B16095617070E02B +:2015C00081E090E0442311F080E090E06817790751F790B181E0211180E0991F9927991F57 +:2015E000891709F326B191E0011190E081E021FF80E09817C1F229B191E0E11090E081E035 +:2016000023FF80E08927D0CF559A209A3A9A3D9A3E9A3B9A239A289A429A45984698439A05 +:201620002B9A8FE781B95C9A599A5A9A5F9A5B9A179A589A409A419AE3E7F0E08081816096 +:201640008083EDE6F0E080818260808380818160808308951F93DF93CF93CDB7DEB72A971C +:201660000FB6F894DEBF0FBECDBFCE010196DC01ECE2F3E02AE001900D922150E1F7E0914B +:201680009A03F0E0F595E795F595E795F595E795F595E7951FB7F894E53008F0E4E0F0E0C2 +:2016A000EE0FFF1FE80FF91F20813181220F331F40E050E060E07DE281E391E00E94DE3DA9 +:2016C0003093A9032093A8031FBF82E086BB2A960FB6F894DEBF0FBECDBFCF91DF911F9135 +:2016E00008951F920F920FB60F920BB60F9211242F933F934F935F936F937F938F939F932E +:20170000AF93BF93CF93DF93EF93FF93489B2FC0E0919A038091A303882309F03DC0F0E045 +:20172000E45DFE4F249130E0220F331F21153105A9F537995DC080919A038F5F80939A0390 +:2017400080919A03882309F064C04598429A4899FECF4298459A7EDFC091E235D091E335B5 +:20176000C330D10508F057C081E080939F03FF91EF91DF91CF91BF91AF919F918F917F91AB +:201780006F915F914F913F912F910F900BBE0F900FBE0F901F90189524E230E080E090E034 +:2017A00040E050E068E18A539A4CFC01808180FF03C0683159F1542F4F5F842F90E08217BD +:2017C00093070CF1561708F4B4CF862FE82FF0E0EA53FA4C908191FF03C0908191609083EE +:2017E0009081946090838F5F581780F7379BA3CF80919A03882309F4A3CF80919A03815072 +:2018000080939A039DCF4831E9F2CDCF542F642FD3CF459A9BCF8DEA93E061E371E046E115 +:2018200050E00E94393EC851DC4FD093C535C093C43510929E0381E080939F038093A00363 +:201840001092E3351092E2358FCF1F920F920FB60F920BB60F9211241F932F933F934F9340 +:201860005F936F937F938F939F93AF93BF93CF93DF93EF93FF9386B190E0959587958170B4 +:2018800090919C03891791F09091A603923009F46DC010929C0311E010939F03C091E235D2 +:2018A000D091E335C330D10508F047C086B1817011E0812790919E038917C9F080939E0357 +:2018C00080919E03882349F546988FE781B980916B008F7780936B00C091E235D091E335FE +:2018E000C330D10508F045C081E080939F03FF91EF91DF91CF91BF91AF919F918F917F913C +:201900006F915F914F913F912F911F910F900BBE0F900FBE0F901F90189511B8469A80912E +:201920006B00806880936B0080B180788093E1351092E3351092E235D7CF8DEA93E061E33D +:2019400071E046E150E00E94393EC053D84FD093C535C093C43510929E0310939F031093B8 +:20196000A0031092E3351092E235A0CF80939C0392CF8DEA93E061E371E046E150E00E9457 +:20198000393EC854D44FD093C535C093C43510929E0310939F031093A0031092E3351092BE +:2019A000E235A2CF1F93E0B1E0688091E2359091E3358430910588F48330910509F487C060 +:2019C000DC01A35EBC4F2C912E1709F404C11092E3351092E2351F910895F0E0EA5DFE4F36 +:2019E000E49132E08F3B930748F59C01237030702230310509F4BBC02330310509F449C15F +:201A00002130310509F418C1EE0FEE0FE093E4354091E83550E09A01220F232F221F330B28 +:201A20002093E935440F551F422B4093E83501969093E3358093E2351F910895F2E08F3BCC +:201A40009F0709F4C1C022E0803C920709F4CEC032E0813C930709F4E2C1F2E0823C9F0741 +:201A600009F0B5CF8091E435982F990F990F9093E435E82B9091E835E917C9F08DEA93E078 +:201A800062E971E046E150E00E94393E80E490E09093C5358093C43510929E0381E0809386 +:201AA0009F038093A0031092E3351092E235E091E535F0E0EA53FA4C808182608083808196 +:201AC0008160808380818B7F80832B9A80CFF0E0EA5DFE4F1491E0919A038091A303882387 +:201AE00009F082C0F0E0E45DFE4FE4911E1708F04DC1E0919A03882309F074C0F0E0E45DA6 +:201B0000FE4FE49180919C03E89F802D1124810F8093E53590E0DC01AA53BA4C2C9122FD01 +:201B2000E0C0982F8827990F8D539C4F9093EB358093EA358C9184608C938C918D7F8C933F +:201B400080919A038093DE3580919C038093DF351093E0352B981092E8351092E735109240 +:201B6000E6358091E2359091E335019661CF5091E435452F407C4E2B2091E6354227843195 +:201B8000910578F0E091EA35F091EB354193F093EB35E093EA355091E4358091E2359091CA +:201BA000E3356091E9352091E73530E0260F311D240F311D2093E7353093E935550F550FA5 +:201BC0005093E435019634CFEE0FEE0FE093E43580EC92E02DCF2091A203222309F0F7CEB6 +:201BE000019626CFE2E18ECFE2E180CF8091E435982F990F990F9093E435807C8E2B9091D4 +:201C0000E635891709F46AC08DEA93E06CE671E046E150E00E94393E8EE390E09093C535E7 +:201C20008093C43510929E0381E080939F038093A00381E090E0FCCE5091E435452F407CC4 +:201C40004E2B2091E83542278431910578F0E091EA35F091EB354193F093EB35E093EA35E7 +:201C60005091E4358091E2359091E3356091E9352091E63530E0260F311D240F311D209367 +:201C8000E6353093E935550F550F5093E4350196CFCE4091E4354E2B2091E7354227843102 +:201CA000910568F0E091EA35F091EB354193F093EB35E093EA358091E2359091E3355091BA +:201CC000E9352091E83530E0250F311D240F311D2093E8353093E9350196AACE81EC92E066 +:201CE000A7CE30919A0320919C038DB79EB70C970FB6F8949EBF0FBE8DBFADB7BEB711963E +:201D00008DEA93E0EDB7FEB79283818386E190E013969C938E93129788E591E015969C9336 +:201D20008E93149716963C93169717961C92179718962C93189719961C9219971A961C931E +:201D40001A971B961C920E94483E8DE390E09093C5358093C43510929E0381E080939F03E9 +:201D60008093A0031092E3351092E2358091E53590E02DB73EB7245F3F4F0FB6F8943EBF67 +:201D80000FBE2DBFDC01AA53BA4CCBCE20919A038DB79EB70A970FB6F8949EBF0FBE8DBFC2 +:201DA000ADB7BEB711968DEA93E0EDB7FEB79283818386E190E013969C938E93129782E468 +:201DC00091E015969C938E93149716961C93169717961C92179718962C93189719961C9262 +:201DE0000E94483E8CE390E09093C5358093C43510929E0381E080939F038093A003109202 +:201E0000E3351092E2358091A3032DB73EB7265F3F4F0FB6F8943EBF0FBE2DBF6ACE8091FE +:201E2000E435982F990F990F9093E435807C8E2B9091E735891759F08DEA93E06FE771E0CA +:201E400046E150E00E94393E8FE390E0E7CE82EC92E0EECD4091A4035091A503E2EEF2E03D +:201E60002591349160E07FEF2627372791EA692F632770E0660F771F6A5D7D4FFB01659111 +:201E80007491322F2227262737279327E92FF0E0EE0FFF1FEA5DFD4F65917491322F2227F3 +:201EA00026273727EBEFE327F0E0EE0FFF1FEA5DFD4F65917491322F222726273727B82FDE +:201EC000BB0FA0E0AD53BC4F80E090E0722F6627ED91E327F0E0EE0FFF1FEA5DFD4F2591F3 +:201EE000349126273727019662E08030960771F73093A5032093A40342175307C9F08DEA3C +:201F000093E065EA71E046E150E00E94393E86E490E09093C5358093C43510929E0381E097 +:201F200080939F038093A0031092E3351092E23508951F920F920FB60F920BB60F921124D7 +:201F40002F933F934F935F936F937F938F939F93AF93BF93EF93FF9390B180919E0388236B +:201F600009F456C0892F80789091E135891709F44FC08093E1359091A303992309F46FC0E3 +:201F8000882309F461C020B12F708091E435282B2093E4358091E2359091E3358230910516 +:201FA00009F45FC0009709F446C08130910509F46DC032E08330930708F458C0A2E0833052 +:201FC0009A0709F49AC0B2E084309B0709F530E08091A4039091A503822B932B9093A5035C +:201FE0008093A4038091E53535DFE091E535F0E0EA53FA4C8081826080838081816080833F +:2020000080818B7F80832B9A1092E3351092E235FF91EF91BF91AF919F918F917F916F917A +:202020005F914F913F912F910F900BBE0F900FBE0F901F901895213A59F781E090E09093D2 +:20204000E3358093E235E4CF80B190E082959295907F9827807F98278093E435D9CFA2DCCE +:20206000D7CF2B3FE9F0213A79F6D2CF3091E535F32FFF0FE0E0E80FF91FE054FC4F208310 +:2020800001969093E3358093E235C2CF213A09F0BBCF82E090E09093E3358093E235B8CF17 +:2020A00083E090E09093E3358093E2352091A7032093E535822F90E0FC01EA53FA4C30816E +:2020C00032FD26C0982F8827990F8D539C4F9093EB358093EA3580818460808380818D7F98 +:2020E000808380919A038093DE3580919C038093DF352093E0352B988BCF1092A403209351 +:20210000A50384E092E09093E3358093E23580CF50919A0340919C032DB73EB72C503040DA +:202120000FB6F8943EBF0FBE2DBFEDB7FEB731962DEA33E0ADB7BEB712963C932E93119795 +:2021400026E130E03383228328E531E0358324835683178240871186938782870E94483E75 +:2021600087E490E09093C5358093C43510929E0381E080939F038093A0031092E3351092F0 +:20218000E2352DB73EB7245F3F4F0FB6F8943EBF0FBE2DBF3DCFF89490919E03992341F4EC +:2021A0008F7782B9459A079BFECF0799FECF4598789408958AE082B9459A079BFECF07990A +:2021C000FECF4598E091A50381EAE827F0E0EE0FFF1FEA5DFD4F859194913091A40320E0A1 +:2021E000822793279093A5038093A40381E182B9459A079BFECF0799FECF45980895982F5E +:2022000092959F7092B9459A079BFECF0799FECF4598482F4F70E091A503E827F0E0EE0F7A +:20222000FF1FEA5DFD4F859194913091A40320E0822793279093A5038093A40342B9459A88 +:20224000079BFECF0799FECF459808952F923F924F925F926F927F928F929F92AF92BF92CE +:20226000CF92DF92EF92FF920F931F93DF93CF9300D00F92CDB7DEB78983692EA0E2CA2EAB +:20228000A3E0DA2E992422243324EE24FF2400E010E088C01070C801880F991F2801440CFB +:2022A000452C441C55085194482A592AF6010191852D9927820D931D800F911DAFEF4A2295 +:2022C0005524D6011196AC906F010894C11CD11CA7014A0D511D9C0120703170232F33270E +:2022E000420F531F3FEF232E312C2822392271802FEFE22EF12CE422F522872C8E240425B3 +:2023000010E0A224BB24F501E07CF070F595E795F595E795F595E795F595E7959801207C29 +:2023200030703595279535952795E22BF32B882D829586958695837090E0E82BF92BE458EE +:20234000FE4F84914A835B8326DF0F73107004581E4FF80184911FDF80919F034A815B813A +:20236000882309F0A9C00894C11CD11C8201070D111D40705170452F5527040F151FF50187 +:20238000EF73F070E458FE4F849105DFE82DF0E0EF73F070E458FE4F8491FDDE9394F92D8C +:2023A000FE3A41F0292D243009F074CF9981C92ED62C70CF1070C801880F991F5801AA0CD5 +:2023C000AB2CAA1CBB08B194A82AB92AD6010C91200E311C8B2D9927280E391E1196CC90AC +:2023E000EC0CF11CC10180709170892F9927E80EF91E0A2510E0C224DD24F601E07CF070E7 +:20240000F595E795F595E795F595E795F595E795C801807C90709595879595958795E82B40 +:20242000F92BE458FE4F8491B6DEF801EF73F070E458FE4F8491AFDEF601EF73F070E4586B +:20244000FE4F8491A8DEF101E07CF070F695E795F695E795C501807C90700024880F991FA3 +:20246000001C880F991F001C892F902DE82BF92BC701807C9070929582958F7089279F7069 +:202480008927E82BF92BE458FE4F849184DEF101EF73F070E458FE4F84917DDEF701EF734E +:2024A000F070E458FE4F849176DEF501EF73F070E458FE4F84916FDE0F900F900F90CF91EA +:2024C000DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F90D9 +:2024E0002F9008951F93CF93DF938FEF99E6A8E181509040A040E1F700C000008CEE95E369 +:2025000063EB71E041E00E94B32E882309F46DC08CEE95E363EC73E040E052E00E944829AA +:2025200097FD78C010920836109207368BE796E10E94483D1FB7F8940E94F23CEC011FBF03 +:202540008CEE95E30E94B22B0E946F23209761F1ADB7BEB718970FB6F894BEBF0FBEADBF3E +:20256000EDB7FEB731968DEA93E012969C938E93119786E190E09383828380ED91E09583C9 +:202580008483D783C6830E94483E8DB79EB708960FB6F8949EBF0FBE8DBF81E00E94240A3A +:2025A000DF91CF911F91089589E062E00E9437228DEA93E060EC71E046E150E00E94393E61 +:2025C0008DEA93E060E044E50E9443228FEF9AE1A7EB81509040A040E1F700C00000FE01FE +:2025E0000995DF91CF911F91089564E00E9437228BE696E060E00E94C4228DEA93E06EE5F5 +:2026000076E00E94053E80E00E94240ADF91CF911F9108958DEA93E06EE476E00E94053EBB +:2026200081E00E94240A7ECFCF93DF930E946F2380E060E00E94372288E396E061E00E94B5 +:20264000C42286E296E00E940C3E8195880F865D62E00E94372286E296E060E00E94C42257 +:202660004DB75EB7485050400FB6F8945EBF0FBE4DBFEDB7FEB73196CDEAD3E0ADB7BEB76F +:202680001296DC93CE93119786E190E09383828382EE91E0958384838091AC0386831782C6 +:2026A0000E94483EFE0101900020E9F73197EC1BFD0B4DB75EB7485F5F4F0FB6F8945EBFAF +:2026C0000FBE4DBF8E2F8195880F865D63E00E943722CE0160E044E50E9443220E94F021A4 +:2026E00093E028E04FEF53ED60E3415050406040E1F700C0000085B1822785B9915091F7BF +:202700000E94F421DF91CF910895CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB765 +:20272000DEB780E060E00E9437220E946F2380E060E00E94372282E196E060E00E94C422F9 +:2027400080E062E00E9437228FEF95E060E00E94C42280E063E00E94372289EF95E060E056 +:202760000E94C422499BFECF4A9BFCCF4C9BFACF80E060E00E9437220E946F2380E062E04F +:202780000E9437228BEE95E060E00E94C42280E063E00E9437228EED95E060E00E94C42232 +:2027A00080E064E00E94372281ED95E060E00E94C4228E010F5F1F4F83EFE82E81E0F82E55 +:2027C000B4E0CB2ED12C16C0809115368F3F29F0809115368F5F8093153680E061E20E9469 +:2027E00028226091153680E00E94282280E060E20E94282280E060E00E94372286EC95E0F7 +:2028000060E00E94C422809115362DB73EB7285030400FB6F8943EBF0FBE2DBFEDB7FEB773 +:202820003196ADB7BEB712961C930E931197D382C282F582E482868317820E94483E2DB734 +:202840003EB7285F3F4F0FB6F8943EBF0FBE2DBFC80160E044E50E9443228FEF99E6A8E1A8 +:2028600081509040A040E1F700C00000499B04C04A9B02C04C99FACF4A9BA6CF49990BC03B +:2028800080911536813808F4A8CF80911536815080931536A2CF4C99A0CF6091153681E0C3 +:2028A00090E00E9490408FEF99E6A8E181509040A040E1F700C000000E946F230F900F9025 +:2028C0000F900F90CF91DF911F910F91FF90EF90DF90CF90089580E060E00E9437220E94E4 +:2028E0006F2380E060E00E94372280EB95E061E00E94C42289E062E00E94372280EA95E07D +:2029000060E00E94C42289E063E00E94372280E995E060E00E94C4228FE065E00E943722F3 +:2029200084E895E060E00E94C422DCCD1F930E946F2380E060E00E94372282E893E060E0A7 +:2029400044E50E94432280E061E00E9437228CEE95E36CE673E043E00E94B32E882309F4C6 +:202960008AC080919803833029F1863019F182E08093A6038CEE95E369E076E34DE056E3BC +:202980000E94D5278823D1F48BE595E060E00E94C4228FEF93E2A4EF81509040A040E1F79D +:2029A00000C0000010E08CEE95E30E94B22B812F1F91089581E08093A603DCCF80E061E090 +:2029C0000E94372280919803853009F4BFC0863008F05FC0833009F4A1C0843039F48DE3F0 +:2029E00095E060E00E94C4228091980391E0863008F490E09093C3354F998CC0992309F453 +:202A00005CC081E08093A20348E754E060E070E08CEE95E30E94CA2A8CEE95E363EC73E072 +:202A200040E052E00E944829E091C303F0E0EC53FC4F10821092D90380E062E00E943722F3 +:202A400084EC93E060E044E50E94432280E064E00E94372282EE94E060E00E94C4228091C7 +:202A6000A203882379F511E08CEE95E30E94B22B812F1F9108958CEE95E36CE673E041E081 +:202A80000E94B32E882309F464C081E08093A20371CF873009F452C0873008F447C0883056 +:202AA00009F0A4CF80EF94E060E00E94C42281E08093A3038091980399CF44E254E060E037 +:202AC00070E0A6CF8DE460E00E94372281E060E00E94282281E068E70E94282281E06EE7A6 +:202AE0000E94282281E069E70E94282281E069E70E94282281E06EE70E94282281E068E75E +:202B00000E94282211E08CEE95E30E94B22B812F1F91089581E08093A20370CF8CE495E02D +:202B200060E00E94C4228091980360CF89E195E060E00E94C4228091980358CF85E095E09E +:202B400060E00E94C4228091980350CF8DE295E0ABCF80E795E060E00E94C4221ACF289837 +:202B60008FE798E3A1E081509040A040E1F700C0000082E282B95D98289A0C947B231F9384 +:202B80001FB7F894E0919A03F0E0EE0FFF1FE850F041808180939A030E94040B10929A03D0 +:202BA00010929B0310929F0310929C0310929D0310929E031092A10382E08093A6031092C5 +:202BC000A7031092A2031092A3031092A0031092AB031092AA031092C5351092C4351092FF +:202BE000E3351092E23580E090E0FC01EA53FA4C1082019688319105C1F711B8469A28981B +:202C00008FE798E3A1E081509040A040E1F700C0000080B18F778093AC0346988FE781B9A2 +:202C2000289A9DDF0E946F231FBF1F910895FF920F931F93CF93DF938C01F090A003C0913D +:202C4000C435D091C5359BDF0E946F2380E060E00E943722FF2009F43FC082E597E061E09D +:202C60000E94C42280E061E00E943722C80160E044E50E9443228DB79EB708970FB6F8946E +:202C80009EBF0FBE8DBFEDB7FEB731960DEA13E0ADB7BEB712961C930E93119786E190E064 +:202CA0009383828386EF91E095838483D783C6830E94483E8DB79EB708960FB6F8949EBF44 +:202CC0000FBE8DBF80E065E00E943722C80160E044E50E944322FFCF8CE397E061E00E946B +:202CE000C42280E061E00E943722C80160E044E50E944322F0CF209107363091083682E00B +:202D00002030380759F0F901ED53FC4F80812F5F3F4F309308362093073608958CEE95E3B9 +:202D200063EC73E040E052E00E94482997FD0BC0109208361092073685B198E0892785B9D2 +:202D400020E030E0E0CF89EF91E071DFF1CF9F92AF92BF92CF92DF92EF92FF920F931F93C0 +:202D6000CF93DF9387E893E10197F1F700C0000029E0E0E0F0E0209357006491A7E8B3E1A1 +:202D80001197F1F700C00000E3E0F0E020935700849190E0E7E8F3E13197F1F700C00000AE +:202DA000E2E0F0E020935700249130E0A7E8B3E11197F1F700C000008A3D910509F418C20B +:202DC000EDB7FEB73C970FB6F894FEBF0FBEEDBF31967DEAC72E73E0D72EADB7BEB7129644 +:202DE000DC92CE92119746E150E05383428349E052E0558344836683178291878087338716 +:202E000022870E94483EEDB7FEB73C960FB6F894FEBF0FBEEDBF81E00E94240A2091AC039E +:202E20002F3709F4F2C12D3049F14DB75EB7485050400FB6F8945EBF0FBE4DBFEDB7FEB704 +:202E40003196ADB7BEB71296DC92CE92119786E190E09383828380E392E095838483268325 +:202E600017820E94483EEDB7FEB738960FB6F894FEBF0FBEEDBF81E00E94240A1092800090 +:202E80001092810080916400886080936400289812B842985D98459881E061E041E021E041 +:202EA00000E0EE240E94BD0A882309F420C211E012B980E061E041E021E000E0EE240E941A +:202EC000BD0A8127C82FD0E012B8429A81E061E041E021E00E94BD0AF82E12B981E061E076 +:202EE00041E021E00E94BD0AF1262F2D30E02C2B3D2B1827122B09F0F0C112B8429852E009 +:202F0000F52EF2B8A12EBB2481E060E041E021E000E0EE240E94BD0A982E12B85D9A81E030 +:202F200061E041E021E00E94BD0A11E09126C92DD0E0812790E0C82BD92BF2B881E061E01C +:202F400041E021E00E94BD0ACA29DB2918271C2B09F0B9C112B85D9844E0F42EF2B8A12E78 +:202F6000BB2481E061E040E021E000E0EE240E94BD0A982E12B8459A81E061E041E021E021 +:202F80000E94BD0A11E09126C92DD0E0812790E0C82BD92BF2B881E061E041E021E00E945B +:202FA000BD0ACA29DB2918271C2B09F082C112B8459880E282B9A12EBB2481E061E041E0DC +:202FC00020E000E0EE240E94BD0AF82E88E082B981E061E041E021E00E94BD0A11E0F12698 +:202FE000CF2DD0E0812790E0C82BD92B88E282B981E061E041E021E00E94BD0ACA29DB294D +:2030000018271C2B09F04BC112B880E182B981E061E041E021E001E0EE240E94BD0AFF247C +:20302000F394F826F12A09F030C112B880E482B981E061E041E021E000E0EE24E3940E94AE +:20304000BD0A91E09827892F90E02F2D30E0822B932B009709F00FC112B8289A90DD489940 +:2030600000C1459A11B8469A8FEF9FEF03C0019709F447C1079BFBCF8FEF9FEF03C00197C8 +:2030800009F449C10799FBCF459846988FE781B981E060E041E020E000E0EE240E94BD0A37 +:2030A000882309F4D4C00AE614E0AA2480E06A2D0E9437223AE1F32E81E060E00E94282267 +:2030C000FA94D1F7F02EE12EC0E0D0E00DC0C701E92FFE2DEC0FFD1F649181E00E942822EC +:2030E0002196C031D10531F09A2D923081F7EAEAF4E0F0CFCFE0D0E00EC0C701E92FFE2D91 +:20310000EC0FFD1F649181E00E9428222197BFEFCF3FDB0731F0AA2DA23079F7EAEAF4E01E +:20312000EFCF2AE1F22E81E060E00E942822FA94D1F7A394005F1F4FEA2DE43009F0B6CF16 +:2031400000D000D000D0EDB7FEB73196ADB7BEB71296DC92CE92119786E190E093838283F6 +:2031600080E492E0958384830E94483EF60101900020E9F73197ED5AF3402DB73EB72A5F06 +:203180003F4F0FB6F8943EBF0FBE2DBF8E2F8195880F865D65E00E943722C60160E044E5DD +:2031A0000E9443222B988FEF93EDA0E381509040A040E1F700C0000085B198E0892785B90F +:2031C0002FEF33ED40E3215030404040E1F700C0000085B1892785B9DF91CF911F910F9151 +:2031E000FF90EF90DF90CF90BF90AF909F9008952C3F310509F0E4CDEDEACE2EE3E0DE2EAC +:203200002091AC032F3709F00ECE00D000D000D0EDB7FEB73196ADB7BEB71296DC92CE9234 +:20322000119786E190E09383828382E292E0958384830E94483EEDB7FEB736960FB6F89461 +:20324000FEBF0FBEEDBF80E00E94240A17CE8DEA93E06AE776E00E94053E81E00E94240A7C +:2032600022CF8DEA93E061EB76E00E94053E81E00E94240AF6CE8DEA93E061EC76E00E94C8 +:20328000053E81E00E94240AE7CE8DEA93E061ED76E00E94053E81E00E94240AC6CE8DEA56 +:2032A00093E065EE76E00E94053E81E00E94240AABCE8DEA93E066EF76E00E94053E81E088 +:2032C0000E94240A74CE8DEA93E065E077E00E94053E81E00E94240A3DCE8DEA93E068E102 +:2032E00077E00E94053E81E00E94240A06CE8DEA93E06BE277E00E94053E81E00E94240AE9 +:20330000D6CD8DEA93E060EA76E00E94053E81E00E94240AB1CE8DEA93E06FE876E00E94B2 +:20332000053E81E00E94240AAFCEE4E6F0E08081877F808383E48093800089E18093810000 +:203340000C942A0B9091A3039923E1F4E82FF0E0E45DFE4FE491F0E0262F30E02E173F0796 +:20336000B4F4AF014F5F5F4F55954795E0FD14C031972E173F0759F06417B0F0862F8F5FC8 +:20338000841B0895262F30E02131310514F080E00895862F8F5F0895E42FF0E031972E17D3 +:2033A0003F0751F780E00895842F860F0895FF920F931F938C01F22E0E94D424882379F15C +:2033C000C80163EC73E30E942C24882391F1E7E1F4E3BF2DBB0FA0E0AD53BC4F81918D934E +:2033E00085E3E33CF807D1F7C80163EC73E30E942C24882311F1E3ECF3E3BF2DBB0FA0E097 +:20340000A159BA4F81918D9384E3E731F807D1F7C8010E94BC241F910F91FF9008958DE4F9 +:2034200092E005DCC80163EC73E30E942C24882371F681E692E0FBDBCACF81E692E0F7DBD4 +:20344000DACF2F923F924F925F927F928F929F92AF92BF92CF92DF92EF92FF920F931F9332 +:20346000DF93CF93CDB7DEB760970FB6F894DEBF0FBECDBF982E792E862E8091A30388239E +:2034800009F4B7C004E210E0F2E14F2E512C80E090E020E0FF24E8E1EE2E76E1A72EB12C34 +:2034A00061E7C62E62E0D62E1801122F8A539A4CDC018C9180FF35C08091DE35881661F1EB +:2034C0008091DE352DB73EB72A5030400FB6F8943EBF0FBE2DBFEDB7FEB731962DEA33E0B4 +:2034E000ADB7BEB712963C932E931197B382A282D582C48286821782808711860E94483EB6 +:203500004DB75EB7465F5F4F0FB6F8945EBF0FBE4DBF8DEA93E08BDB5E2D583109F466C071 +:20352000F12E1F5F812F90E0821593050CF45AC0BE2DB83109F43EC08091A203882361F400 +:2035400066C0EE2DF0E0EA53FA4C80818E7F808380818B7F8083E394FE1498F7EDB7FEB747 +:2035600038970FB6F894FEBF0FBEEDBF31960DEA13E0ADB7BEB712961C930E93119786E164 +:2035800090E09383828386E892E095838483868217820E94483EEDB7FEB738960FB6F89460 +:2035A000FEBF0FBEEDBF80E065E061D7C80160E044E569D760960FB6F894DEBF0FBECDBF49 +:2035C000CF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F905F904F903F9067 +:2035E0002F900895183109F4A3CF60CFF12EE12E98CFE62FF0E0E45DFE4FE4914E2E552416 +:203600008201000F111F01151105A1F240CFE8D613D76B877C878D879E87FE1408F461C114 +:20362000482D50E05A8749871A01220C331CC101880F991F880F991F880F991F820D931DAE +:203640009C0140E050E029833A834B835C830E2DF101E457FF4F859194919C0140E050E089 +:203660002D833E834F8358871E2DAF2C42C08090DF352091A60330E040E050E069817A813D +:203680008B819C810E94893D6B017C018091093690910A36A0910B36B0910C36C80ED91E3D +:2036A000EA1EFB1E282D30E0429EC001439E900D529E900D1124AA2797FDA095BA2FC80E4A +:2036C000D91EEA1EFB1EC00ED11CE11CF11C2F853889322F2227330F2D533C4F892D972D27 +:2036E000B701A6010E94F424882371F10F5FA01688F1402F50E0588B4F87FA01EA53FA4C31 +:20370000808180FDF3CF8091A303882309F0AFCFC0900936D0900A36E0900B36F0900C36EE +:20372000C00ED11CE11CF11C2091A60330E040E050E06D817E818F8198850E94893DC60EB4 +:20374000D71EE81EF91EC3CF8BE992E070DA0F5FA01678F6E12EFA2C8091A303882309F073 +:203760004FC0F101E457FF4F65917491A0900936B0900A36C0900B36D0900C36AE0CB11C1B +:20378000C11CD11C80E090E02091A60330E040E050E00E94893DA60EB71EC81ED91E0F2DCB +:2037A00010E00F5F1F4F0E191109222717FD2095322F892D972DB601A5010E948F268823B0 +:2037C00059F487C0F801EA53FA4C80818E7F808380818B7F8083E394FE14D0F10E2D10E045 +:2037E000B801762F6627770F6D537C4F892D972D0E941D26882331F78EEB92E018DAE2CF0D +:203800008091DF3590E0489E5001499EB00C589EB00C1124CC24B7FCC094DC2C8091093603 +:2038200090910A36A0910B36B0910C36A80EB91ECA1EDB1EAE0CB11CC11CD11CB101660F4C +:20384000771F660F771F660F771F620D731D9ACF892D972D0E94D026882309F43EC089E132 +:203860008093AB03C1D5E8D5ADB7BEB71C970FB6F894BEBF0FBEADBFEDB7FEB731960DEA8A +:2038800013E012961C930E93119726E130E0338322832FED32E03583248329853A8537836F +:2038A00026832B853C854D855E85621B730B840B950B60877187828793870E94483E4DB7E1 +:2038C0005EB7445F5F4F0FB6F8945EBF0FBE4DBF6ACE8BEA92E0ABD97FCF8DEC92E0A7D9DF +:2038E000BECF282D30E03A8729871901220C331C33CF2F923F924F925F926F927F928F9235 +:203900009F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7CD54D0400FB6C9 +:20392000F894DEBF0FBECDBF55D529D9499B04C04A9902C04C9B07C0499904C04A9902C093 +:203940004C9901C004DAF1DC0E941413C8D678948FE79AE1A6E081509040A040E1F700C013 +:2039600000003ED58FE79AE1A6E081509040A040E1F700C00000499B06C04A9904C04C996E +:2039800002C00E94851389E189831C821C8E1BA21EA28E010F5F1F4FC80161E00E94352F75 +:2039A000882309F49BC45DEA852E53E0952E1CD5499906C04A9904C04C9B02C00E946B1406 +:2039C000C8010E943506C8010E944808222433248091A003882309F078C0F894D0909A03D0 +:2039E000C0909C0310929F0378948091A103882309F07EC080919F03882351F74B9B04C0A1 +:203A000007996DC0F1010995499918C080916A0390916B03009771F3019790936B0380934B +:203A20006A03C8010E9448088FEF94E3ACE081509040A040E1F700C00000DCCF4A9B49C02B +:203A40004C99D8CF80919803813009F405C3823009F499C2809168008860809368008091C1 +:203A60006800846080936800809168008460809368008091680081608093680010929A0393 +:203A80002ED60E949614882309F4A2CF8091A20391E089279091A303992309F4826082B949 +:203AA000459AA7E8B3E11197F1F700C000004598B2E4BA95F1F700C04298E1E0E093A10398 +:203AC0008091A003882309F488CF8DEA93E0AFD884CF80916A0390916B0301969ECF89B124 +:203AE00080FF90CF86B180FF8DCF31998DCF8ACFED2CFF242DB73EB7285030400FB6F89409 +:203B00003EBF0FBE2DBFEDB7FEB73196ADB7BEB712969C928E92119726E1422E512C53828F +:203B2000428294E1692E93E0792E75826482F782E6820E94483E2DB73EB7285F3F4F0FB602 +:203B4000F8943EBF0FBE2DBF88E164E090D4C40160E044E598D4AC2CBB248DB79EB7089789 +:203B60000FB6F8949EBF0FBE8DBFEDB7FEB73196ADB7BEB712969C928E921197538242824E +:203B800089E1482E83E0582E55824482B782A6820E94483E2DB73EB7285F3F4F0FB6F894F7 +:203BA0003EBF0FBE2DBF88E364E061D4C40160E044E569D480919B038D1509F4BDC1609143 +:203BC0009B03C8013EDCD0929B03C0929D0380E090E0FC01EA53FA4C20812D7F208301969B +:203BE00088319105B1F780919F03882309F0F0CE80919E03882309F091C13D2D303598F7B3 +:203C00008091A303882309F0BCC1F701E45DFE4F24918091A703821710F01092A70386B1BA +:203C20004B9903C3881F8827881F8EAF2C9D902D112423969FAF2397A701440F551FCA01EA +:203C4000880F991F880F991F880F991F840F951F28968FAF289729969FAF299730E02A9DD1 +:203C6000C0012B9D900D3A9D900D11242C01662457FC6094762C27964CAE5DAE6EAE7FAECA +:203C800027970E2CEF2C000CEE1CFF08000CEE1CFF1CAA0CBB1CA294B294E0EFBE22BA242D +:203CA000AE22BA245E2C5A285FAE852D90E084589E4F44575F4FFA01659074902B967FAE27 +:203CC0006EAE2B972D2D2F7321962FAF2197E22FF0E0E458FE4F34912C963FAF2C97FC011E +:203CE000F4912D96FFAF2D972296DFAE22972E96CFAE2E972401F6B0F094FF1CFF24FF1C5E +:203D000009F474C16EAC6F1461F080E464E0AFD3FF2009F491C186ED94E060E035D421E0BA +:203D20002EAF8091AB03813009F48CC18091A303882309F40CC1E090A703F8946E2C7724E5 +:203D400076EC872E75E3972E860C971CD4018C9181FDF0C08C9182FDEDC08C9184608C9361 +:203D600081E07894882309F441C08091A303882309F054C12B966EAD7FAD2B978091A70338 +:203D8000A0900936B0900A36C0900B36D0900C36A80EB11CC11CD11C27968CAD9DADAEAD19 +:203DA000BFAD2797A80EB91ECA1EDB1E80E090E02091A60330E040E050E00E94893DA60EC5 +:203DC000B71EC81ED91E0CD38091C335882309F413C1C801B601A5012E2DE9DA05D3D401DC +:203DE0008C9182608C938C918B7F8C938091A703882301F5FF2059F085B1B8E08B2785B9DD +:203E00008091AB03823018F081508093AB032091AA03275E2093AA032D3708F008C130E01F +:203E20008091A8039091A903821B930B90938900809388008091A303882309F48FC052E394 +:203E4000F52E05C08EE40E94FF10FA9431F080919F038823B9F34201BBCD80919F03882375 +:203E6000D1F70E94FF10F394EF2DEC30B1F72FEF3FEF3093A5032093A4030E94DA100E9423 +:203E8000DA100E94DA1080919F03882321F78EEF0E94FF1080919F038823E9F622968FADD7 +:203EA00022970E94FF1080919F038823A1F62E968FAD2E970E94FF1080919F03882359F680 +:203EC0008091A7038F5F0E94FF1080919F03882311F682E00E94FF10F090A4038091A50330 +:203EE00090919F03992309F0B6CF0E94FF1080919F03882309F0AFCF8F2D0E94FF10FF24AF +:203F000008C08EE40E94FF10F3943F2D363109F4A8C180919F038823A1F39DCF80E464E0F0 +:203F2000A6D28CED94E060E02FD380919F038823E1F359CE80E015CF8091A303882309F4DE +:203F400052CE80919D038C1509F039CE4CCEE090A70323963FAD2397E30EEFCE27E3E22E94 +:203F6000F12C0AC08FEF0E94CB100894E108F108E114F10409F489C080919F03882391F3CF +:203F80006ACF22E146CE80919903815080939903C80161E00E94BB2E80919903882389F03E +:203FA000FF249F2DADE09A9FB00111246D537E4CC80141E00E94D92EF39480919903F81607 +:203FC00080F310926B0310926A0389D3C8010E943506C8010E9448088FEF99E6A8E181503B +:203FE0009040A040E1F700C00000F2CCC80122966FAD229726DA86CE9301322F2227330F91 +:204000002D533C4FC801B601A501EED4882309F0E5CE89EF91E00E941716E0CE28969FADE6 +:20402000289729968FAD2997692F782FA7CE1092AA0320E030E0F4CE80ED94E060E0A4D29A +:204040002B9A1EAE1092AB0380E065E010D28AEB94E060E099D26ACEF0909903AF2DBDE097 +:20406000AB9FC00111248D539E4C6CE673E04DE050E00E94393EF394F0929903C8016CE65B +:2040800073E041E00E94D92E9CCF8091A603823009F4E4C082E0F82EE090A70380919F0336 +:2040A000882309F0D8CE85ED0E94CB1080919F03882309F0D0CE8AEA0E94CB1080919F032E +:2040C000882309F0C8CE86E90E94CB1080919F03882309F0C0CE2C968FAD2C970E94CB1097 +:2040E00080919F03882309F0B6CEE091A703F0E0E458FE4F84910E94CB1080919F03882381 +:2041000009F0A9CE2D968FAD2D970E94CB1080919F03882309F09FCEEF2DF0E0E458FE4FB6 +:2041200084910E94CB1080919F03882309F093CE2196EFAD2197EE252FADE227EF25EF73BC +:20414000F0E0E458FE4F84910E94CB1080919F03882309F080CE8EED0E94CB1080919F0324 +:20416000882309F078CE8AEA0E94CB10BAE0FB2E80919F03882309F06ECE8FEF0E94CB1013 +:20418000FA94B1F780919F03882309F064CE85ED0E94CB1080919F03882309F05CCE8AEA7C +:2041A0000E94CB1080919F03882309F054CE8DEA0E94CB1080919F03882309F04CCEE09133 +:2041C000A703F0E0E458FE4F84910E94CB10C301982F8827990F8D539C4F0E9426118091B3 +:2041E0009F03882309F037CE8EED0E94CB1080919F03882309F02FCE8AEA0E94CB10809126 +:204200009F03882309F027CE8FEF0E94CB1022968FAD22976091A70395D88093A7034B9B10 +:204220006ACD2296DFAC229742014598429A1092A103C8016D2D05D98FE79AE1A6E0815080 +:204240009040A040E1F700C000000E94BF15C8010E943506C8010E944808BACB92E2F92E1F +:204260001BCF4CE0F42E80919F03882309F0F3CD0E94FF10FA94B9F78FEF9FEF9093A50329 +:204280008093A4030E94DA100E94DA100E94DA1080919F03882309F0DECD8BEF0E94FF1093 +:2042A0006301DC2CCC24DD0CA3ECB3E0CA0EDB1EEE24FF240BC00E94FF100894E11CF11C6F +:2042C000F0E0EF16F2E0FF0609F468C0F60181916F0190919F03992371F3BDCD00D000D087 +:2042E00000D0EDB7FEB731964DEA842E43E0942EADB7BEB712969C928E92119736E1E32E61 +:20430000F12CF382E28287EF92E0958384830E94483EF40101900020E9F73197E819F90927 +:204320002DB73EB72A5F3F4F0FB6F8943EBF0FBE2DBF8E2F8195880F865D64E098D0C401C8 +:2043400060E044E5A0D08DB79EB70A970FB6F8949EBF0FBE8DBFEDB7FEB73196ADB7BEB78A +:2043600012969C928E921197F382E28283E093E0958384838981868317828B81808711867B +:204380000E94483EEDB7FEB73A960FB6F894FEBF0FBEEDBF80E00E94240A09CBF090A4031A +:2043A0008091A50390919F03992309F054CD0E94FF1080919F03882309F04DCD8F2D0E942B +:2043C000FF1025CF81E090E00C94110A80E090E00C94110A14BC83E085BD81E085BB089510 +:2043E00081E080936E00089510926E0008951F920F920FB60F9211248F939F93AF93BF93BC +:204400008091113690911236A0911336B09114360196A11DB11D8093113690931236A093BB +:204420001336B0931436BF91AF919F918F910F900FBE0F901F9018952FB7F89460911136B5 +:204440007091123680911336909114362FBF089590E59CBD1DBC882341F05E9A2A986EBD5B +:204460000DB407FEFDCF2A9A08955E98F7CF1F93162F682F606880E0EBDF612F606480E059 +:20448000E7DF1F910895AF92BF92CF92DF92EF92FF920F931F93CF93DF93D62EC42EE82E5F +:2044A000F92EBB248FE7A82EF70101917F01002359F4DF91CF911F910F91FF90EF90DF9093 +:2044C000CF90BF90AF900895BC1498F70D3609F183E0089F80011124E801C85FD84F065F5A +:2044E000184FFE016491660FD1106A2581E0B0DFB394C017D10749F4BC14B0F6DD20C1F134 +:204500006FE781E0A5DFB394CFCF2196BC1460F6E8CFDD2079F163E481E09ADFB394BC1448 +:2045200008F0C2CFDD2051F16BE781E091DFB394BC1408F0B9CFDD2029F167E681E088DFCD +:20454000B394BC1408F0B0CFDD20D1F06BE781E07FDFB394BC1408F0A7CFDD2069F067E4D8 +:2045600081E076DFB394BC1408F09ECFDD2041F660E0C7CF6CE3D0CF68E3F2CF64E0D5CF1D +:2045800064E0E5CF68E1DACFCF92DF92EF92FF920F931F93CF93DF93D62E8C010F5F1F4FB8 +:2045A0002FE7C22EF8013197E491EE2331F1ED3679F183E0E89FF0011124EF01C85FD84FB1 +:2045C0009BE0E92E97E0F92EEE0EFF1EFE016491660FD1106C2581E03BDF2196CE15DF05BE +:2045E000A9F7DD2099F06FE781E032DF0F5F1F4FF8013197E491EE23D1F6DF91CF911F9163 +:204600000F91FF90EF90DF90CF90089560E0ECCFDD2089F081E063E41BDF81E06BE718DFC4 +:2046200081E067E615DF81E06BE712DF81E067E40FDF6FE7D9CF81E06CE30ADF81E064E05E +:2046400007DF81E068E104DF81E064E001DF81E068E3FEDE60E0C8CFEF92FF920F931F939D +:20466000CF93DF93E82EF92EF70101917F010023E1F00D3609F183E0089F80011124E80145 +:20468000C85FD84F055F184FFE016491606481E0DFDE2196C017D107B9F781E060E4D8DEBA +:2046A000F70101917F01002321F7DF91CF911F910F91FF90EF90089581E06EE5C9DE81E02E +:2046C00062E4C6DE81E06CE4C3DE81E062E4C0DE81E06CE5BDDE81E060E4BADEC5CFCF93D9 +:2046E000DF93C8EFD1E081E060E0B2DE2197D9F7DF91CF91089584EB8093153684E1809375 +:20470000163684E080931736569A279A259A229A209A2A9880E090E00E948840813FE1F016 +:2047200080E090E061EF0E9490406091153681E090E00E94904080E061E28ADE6091153621 +:2047400080E086DE6091163680E082DE80E060E27FDE80E06CE07CCE81E090E00E94884068 +:2047600080931536E8CFFC014181842F90E09C013595279520652CBD40FD06C081E04630D7 +:2047800019F08DBD2C98089580E08DBD2C980895BF92CF92DF92EF92FF920F931F93CF936F +:2047A000DF938C016B017A0147DEEB01BB24BA94BEBC0DB407FEFDCF8EB5F80182838F3FBA +:2047C000B1F43ADE6C1B7D0B81E06D32780780F381E1F80180832C9A80E0DF91CF911F9117 +:2047E0000F91FF90EF90DF90CF90BF9008958E3F19F08FE08083EFCFE114F104F1F00894E4 +:20480000E108F1088FEF8EBDE114F10471F0F60180E090E03FEF0DB407FEFDCF2EB5219384 +:204820003EBD01968E159F05B0F30DB407FEFDCF8EB5F601EE0DFF1D80838FEF8EBD0DB48C +:2048400007FEFDCF8EB58FEF8EBD0DB407FEFDCF8EB52C9A81E0C1CF0F931F93CF93DF93C7 +:20486000EC018B0180DFCE01B80140E052E090DFDF91CF911F910F910895FF920F931F9375 +:20488000CF93DF93EB01D8DD8B01FF24FA94FEBC0DB407FEFDCF8EB58F3F69F0CDDD601B8B +:2048A000710B6C177D0798F380E0DF91CF911F910F91FF90089581E0DF91CF911F910F91BD +:2048C000FF900895DF92EF92FF920F931F93CF93DF93EC01D62E79018A0145DFCE016CE2CA +:2048E00071E0CBDF8D2D80648EBD0DB407FEFDCF28E130E0D801C701022E04C0B695A7950D +:20490000979587950A94D2F78EBD0DB407FEFDCF285030408FEF283F380761F7DD20E9F0D1 +:204920008D2D883001F587E88EBD0DB407FEFDCF8D2D8C30D1F02FEF9FEF9EBD0DB407FEBF +:20494000FDCF8EB58A8387FD0AC0DF91CF911F910F91FF90EF90DF90089585E9E5CF22234C +:20496000A1F32150EACF8FEFDFCF8FEF8EBD0DB407FEFDCF8EB5DFCFCF93DF93EC01F3DE6F +:20498000CE016CE020E030E0A9019CDF882339F083E088832C9A80E0DF91CF9108952C9A2C +:2049A00081E0DF91CF910895CF93DF93EC019A01AB018B81833039F069E0220F331F441F0A +:2049C000551F6A95D1F7CE0162E17CDF882339F085E088832C9A80E0DF91CF9108952C9A92 +:2049E00081E0DF91CF910895CF92DF92EF92FF920F931F93CF93DF93EC017A018B0169017F +:204A00008B81833039F0A9E0EE0CFF1C001F111FAA95D1F7CE0161E1A801970153DF88238B +:204A200069F084E088832C9A80E0DF91CF911F910F91FF90EF90DF90CF900895CE01B60169 +:204A400040E052E0A5DEF1CF8F929F92BF92CF92DF92EF92FF920F931F93DF93CF930F9271 +:204A6000CDB7DEB74C01B62EFC0113821082E4DC8B01249A2C9A2698259A279A249A2C9A36 +:204A800085E0F401818382E58CBD1DBC8AE09FEF9EBD0DB407FEFDCF8150D1F7C40160E0AC +:204AA00020E030E0A9010EDF782FF40182838130C9F0C2DC601B710BF7E0613D7F0770F351 +:204AC00081E0F40180832C9A80E00F90CF91DF911F910F91FF90EF90DF90CF90BF909F903E +:204AE0008F900895C40168E02AEA31E040E050E07983E8DE798182FF1FC0F4017383CC2481 +:204B0000DD247601C40167E320E030E0A901DADEC40169E2A7019601D5DEF40182838823F5 +:204B2000D9F08ADC601B710BF7E0613D7F0750F38AE0F4018083C7CF84E02FEF2EBD0DB4EB +:204B400007FEFDCF9EB5F40192838150B9F79A3A79F082E08083B7CF83818230B1F02C9A61 +:204B6000FB2DF73070F088E1F401808380E0ADCF82E0F4018383C12CD12CE12CB0E4FB2E38 +:204B8000C1CFF401B18281E0A0CFC4016AE320E030E0A90197DE882321F088E0F401808330 +:204BA00092CF8FEF8EBD0DB407FEFDCF8EB5807C803C19F483E0F401838383E09FEF9EBD87 +:204BC0000DB407FEFDCF2EB58150C9F7C8CFFC016EBDA42FB52F80E090E00DB407FEFDCFF7 +:204BE0002C912EBD0DB407FEFDCF11962C9111972EBD0296129622E08030920771F70DB4D0 +:204C000007FEFDCF8FEF8EBD0DB407FEFDCF8FEF8EBD0DB407FEFDCF8FEF8EBD0DB407FE7E +:204C2000FDCF8EB582838F71853029F083E180832C9A80E0089581E008950F931F93CF93B4 +:204C4000DF93EC018B018FDDCE0168E572E015DE882349F485E188832C9A80E0DF91CF914D +:204C60001F910F910895CE016CEFA801B0DF882389F32C9A81E0DF91CF911F910F910895DA +:204C8000CF92DF92EF92FF920F931F93CF93DF93EC017A018B0169018B81833039F089E059 +:204CA000EE0CFF1C001F111F8A95D1F7CE0168E1A801970107DE882369F086E088832C9A30 +:204CC00080E0DF91CF911F910F91FF90EF90DF90CF900895CE016EEFA60179DF882379F399 +:204CE000CE0168E572E0C9DD882319F487E18883E6CFCE016DE020E030E0A901E3DD88237F +:204D000019F086E18883DBCF8FEF8EBD0DB407FEFDCF8EB58823A9F72C9A81E0D2CFAF927C +:204D2000BF92CF92DF92EF92FF920F931F93CF93DF93EC015A016B017801890167E320E015 +:204D400030E0A901BFDDCE0167E1A8019701BADD882379F089E088832C9A80E0DF91CF9190 +:204D60001F910F91FF90EF90DF90CF90BF90AF9008958B81833039F099E0AA0CBB1CCC1C06 +:204D8000DD1C9A95D1F7CE0169E1A60195019ADD882319F087E08883DFCF2C9A81E0DECFAE +:204DA000CF93DF93EC01DFDCCE0168E572E065DD882359F08DEF8EBD0DB407FEFDCFCE01AB +:204DC00068E572E05ADD882339F482E188832C9A80E0DF91CF9108952C9A81E0DF91CF912D +:204DE0000895CF93DF93EC019C012C5F3F4F898D9A8D41E050E060E070E00E948331882380 +:204E0000D9F08D899E89AF89B88D0097A105B10579F48C819D81AE81BF818D8B9E8BAF8B9A +:204E2000B88F89818068898381E0DF91CF91089581E0DF91CF91089580E0DF91CF910895C4 +:204E4000CF92DF92EF92FF921F93CF93DF93EC0189899A89AB89BC89803E2FEF92072FE1C8 +:204E6000A20720E0B20748F080E0DF91CF911F91FF90EF90DF90CF900895CE01B2DF882334 +:204E800099F30E94572F882379F3E98DFA8DCC80DD80EE80FF808EEF9FEFAFEFBFEFC80E87 +:204EA000D91EEA1EFB1E058404C0CC0CDD1CEE1CFF1C0A94D2F786859785A089B189C80ED0 +:204EC000D91EEA1EFB1E81E080932438C0921E36D0921F36E0922036F092213680E092E01A +:204EE000E2E2F6E3DF019C011D9221503040E1F7E98DFA8D84818230C0F011E006C01F5F97 +:204F0000E98DFA8D8481181780F4B701A601410F511D611D711D809122389091233822E2D8 +:204F200036E3AEDE882359F79FCF20E032E040E050E0058404C0220F331F441F551F0A94BC +:204F4000D2F789899A89AB89BC89820F931FA41FB51F898B9A8BAB8BBC8B81E086CFCF9332 +:204F6000DF93EC018C859D85AE85BF8541E0662309F440E0BC01CD01DAD7882381F0288958 +:204F800030E0220F331F22953295307F3227207F32272E5D394CC901DF91CF91089520E0B9 +:204FA00030E0C901DF91CF9108956F927F928F929F92AF92BF92CF92DF92EF92FF920F932E +:204FC0001F93DF93CF9300D000D0CDB7DEB76C014B013A01DC015596ED90FD900D911C9181 +:204FE0005897E114F10401051105F1F05E010894A11CB11C10C0D801C7010196A11DB11DC2 +:2050000029813A814B815C8182179307A407B507F9F47C018D01F601818D928DB801A7016B +:205020009501CAD7882339F780E00F900F900F900F90CF91DF911F910F91FF90EF90DF90E5 +:20504000CF90BF90AF909F908F907F906F900895D60159966D917C915A97FB0187898031EB +:2050600009F44CC0283F8FEF38078FEF48078FE05807D0F2F60185899689A789B08D02977C +:20508000A109B109FB01058404C0880F991FAA1FBB1F0A94D2F72685378540895189820F6F +:2050A000931FA41FB51FF40180839183A283B383FB0186859785A089B1890197A109B109BE +:2050C0002481820F911DA11DB11DA80197012250304040405040058404C0220F331F441FFA +:2050E000551F0A94D2F7820F931FA41FB51FF30180839183A283B38381E097CF283FFFEF79 +:205100003F07F0E04F07F0E05F0708F0B3CF8CCFE82FF92F80E090E03EE209C0DB01A90F8C +:20512000B11D2C939F5F8F5F31968B3061F020812032C9F3883091F7DB01A90FB11D3C9303 +:205140009F5F2081EBCF690F711DFB01108208951F93FB012BE030E231932150E9F7A82F0E +:20516000B92F30E017E09A2F8B2F2D91222351F4FA019083818381E0FB019081903279F0CA +:205180001F9108952F32A1F32E3261F085E898E0FC010196E491EE2351F02E17C9F780E077 +:2051A0001F9108951A30D9F338E01AE0DCCF1317B0F32132A0F32F3790F7FB01E30FF11D33 +:2051C000822F81568A3108F4205220833F5FCBCF0F931F93CF93DF93EC018B018B818823EB +:2051E00031F4FB018789803141F08032F1F180E0DF91CF911F910F91089582E08B831D8AD4 +:205200001E8A1F8A188E808D918DA0E0B0E0880F991FAA1FBB1F880F991FAA1FBB1F880FE1 +:20522000991FAA1FBB1F880F991FAA1FBB1F880F991FAA1FBB1F898B9A8BAB8BBC8B1A8FD0 +:20524000098F81E089831C821D821E821F82188619861A861B861C861D861E861F86188A1D +:20526000DF91CF911F910F91089583E08B83F801428D538D648D758D4D8B5E8B6F8B788FA3 +:205280009E012F5E3F4FC80124D78823C1F6AFCF2F923F924F925F926F927F928F929F92E8 +:2052A000AF92BF92CF92DF92EF92FF920F931F93CF93DF938C01362FE72F2A01DC01139697 +:2052C0002C911397222329F011968C91119780FD16C02FEF3FEFC901DF91CF911F910F9114 +:2052E000FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F902F900895E80106 +:20530000C988DA88EB88FC88488559856A857B854201AA24BB24D701C601841B950BA60BCA +:20532000B70B88169906AA06BB0608F093C04114510409F4BEC0832E9E2E6201A4E02A2ED1 +:20534000312C200E311E612CF2E07F2E60C0FF2009F07AC0411551056105710509F0ABC009 +:20536000E8018D899E89AF89B88D8C839D83AE83BF8346855785608971894F0D511D611D16 +:20538000711D0297A109B109058404C0880F991FAA1FBB1F0A94D2F7480F591F6A1F7B1FEA +:2053A000E301CA19DB09CC16DD0608F4E601E2E0C030DE0709F452C0CB01BA0140E0B7D5C1 +:2053C000882309F486CF95012E5D394CC401B901AE010E94223EAE0160E070E0F8018085BD +:2053E0009185A285B385480F591F6A1F7B1FD80118964D935D936D937C931B97CC1ADD0A61 +:2054000009F457C08C0E9D1E13962C911397EFEFAE2EE1E0BE2EA422B5222230B9F1D8013A +:205420005996ED91FC915A97DB01CA0129E0B695A795979587952A95D1F7F480FA94F8225F +:20544000A114B10409F483CFE8018C819D81AE81BF818FCF2601441A550A69CF80911E3631 +:2054600090911F36A0912036B0912136481759076A077B0709F4A0CF809122389091233892 +:205480009401B2DA882309F0A6CF23CF39E076956795579547953A95D1F7E801E98DFA8D7B +:2054A000828D938DA48DB58D480F591F6A1F7B1F77CF920110CFD80114964D915D916D9153 +:2054C0007C911797CF01910177D5882309F401CFE801E98DFA8D8C819D81AE81BF8149CF53 +:2054E000DF93CF930F92CDB7DEB7BE016F5F7F4F41E050E0CDDE8130910539F02FEF3FEF0B +:20550000C9010F90CF91DF910895298130E0C9010F90CF91DF910895EF92FF920F931F93BF +:20552000CF93DF93EC018B81823050F420E030E0C901DF91CF911F910F91FF90EF90089503 +:20554000E884F9840A851B85CE01CADF97FDEECF88859985AA85BB854F96A11DB11D888750 +:205560009987AA87BB87D801C70115E0B695A795979587951A95D1F78F70282F30E0220F25 +:20558000331F22953295307F3227207F32272E5D394CCECF8F929F92AF92BF92CF92DF92D8 +:2055A000EF92FF920F931F93CF93DF93EC014A015B012B81222309F465C089899A89AB89A1 +:2055C000BC8984179507A607B70708F45BC0223009F452C081149104A104B10409F46AC0C1 +:2055E000488559856A857B85E98DFA8D258530E0275F3F4FDB01CA010197A109B109022E73 +:2056000004C0B695A795979587950A94D2F7850174010894E108F1080109110904C0169584 +:205620000795F794E7942A95D2F7E816F9060A071B07B0F58D899E89AF89B88D8C839D8382 +:20564000AE83BF8384E0C82ED12CCC0EDD1E0FC04C815D816E817F81898D9A8D9601ACD4EE +:205660000894E108F10801091109882359F0E114F1040105110561F788869986AA86BB8698 +:2056800081E001C080E0DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F90089513 +:2056A000411551056105710529F2E81AF90A0A0B1B0BC8CF1C821D821E821F8218861986B5 +:2056C0001A861B8681E0DFCF0F931F93CF93DF93EC018B81882349F0898187FD0EC0E7D35F +:2056E000DF91CF911F910F91089581E0888380E0DF91CF911F910F910895CE0161E02FDC49 +:205700008C01009791F3FC018081853E71F38B818230F8F08D899E89AF89B88DF801938F41 +:20572000828FB58BA48BE0911A36F0911B36309759F0B8016A5E7F4FC80148960995F801B9 +:20574000808D918D938B828B89818F778983AFD3C7CF89899A89AB89BC89848F958FA68FA5 +:20576000B78FD8CFCF93DF93EC01AEDF1B82DF91CF9108956F927F928F929F92AF92BF92EE +:20578000CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB7DEB77C015A016B01DC0123 +:2057A00013968C9113978130A1F080E00F900F900F900F90CF91DF911F910F91FF90EF902D +:2057C000DF90CF90BF90AF909F908F907F906F90089511968C91119781FFE7CFF7018189D0 +:2057E0009289A389B48984179507A607B707E8F20097A105B10529F1F701608471848284C5 +:205800009384C701B601A501C5DE882371F2A114B104C104D104B9F4D70155964D915D915B +:205820006D917C91589759968D919C915A97A3D6882309F4BACFF701158A168A178A108E23 +:2058400040C081E0B3CFD70114964D915D916D917C91179759968D919C915A979E012F5F06 +:205860003F4FAAD3882309F4A0CFD7015996ED91FC915A9749815A816B817C8187898031F4 +:20588000C9F1483F8FEF58078FEF68078FE07807C0F4CF0170D6882309F487CFD7011496C5 +:2058A0004D915D916D917C91179759968D919C915A970FEF1FEF2FEF3FE086D4882309F4ED +:2058C00074CFF701A18AB28AC38AD48A818180688183C701F9DE882309F467CFB601A501B3 +:2058E0006A147B048C049D0410F4B401A301C70151DE5CCF483FBFEF5B07B0E06B07B0E0D2 +:205900007B07F8F6C6CF1F93CF93DF93EC01142FE62FF0E0EE0FFF1FE295F295F07FFE273A +:20592000E07FFE27DF01AE5DB94C1B968C911B97817149F0842F827131F01B8280E0DF9114 +:20594000CF911F91089580911E3690911F36A0912036B09121368C879D87AE87BF87688BFB +:20596000EE5DF94C84899589A0E0B0E0DC01992788278D8B9E8BAF8BB88F428D538D60E05F +:2059800070E0482B592B6A2B7B2B4D8B5E8B6F8B788F838590E0887190700097F1F4848DC5 +:2059A000958DA68DB78D898B9A8BAB8BBC8B81E08B83812F8F7089831C821D821E821F82F0 +:2059C000188619861A861B8614FD17C015FD1EC081E0DF91CF911F9108958031910509F0B3 +:2059E000ACCF9E012F5E3F4F898D9A8D72D3882309F4A3CF84E08B83DCCFCE0140E050E09A +:205A0000BA01B8DE882311F780E099CF49895A896B897C89CE01BEDD92CF8F929F92AF92AE +:205A2000BF92CF92DF92EF92FF920F931F93CF93DF935C01EB01C42E952E822E898D9A8D1E +:205A4000D5015A969C938E935997CB0140E050E0BA01A0DDDD24E884F9840A851B858989C1 +:205A60009A89AB89BC89E816F9060A071B0708F040C0CE0151DDFC01009709F476C0D801C5 +:205A8000C70115E0B695A795979587951A95D1F7182F1F708081882391F0853E81F08C2D13 +:205AA000992DBF014BE050E00E94153E009799F687FC5BC0C501612F482D25DF57C0DD2069 +:205AC000A9F420911E3630911F364091203650912136D5011C962D933D934D935C931F9712 +:205AE00050961C9350978081DD24D394882309F0B2CF86FE3AC081FE38C0DD2009F043C0AE +:205B00008B81823091F1CE019BD9882371F1C2E2D6E310E07E01EC2FFF2D80E2DF011D92F1 +:205B20008A95E9F7DE018C2D992DFC018BE001900D928150E1F7E0911A36F0911B3630976D +:205B400061F1BE01625F7F4FCE0140960995888999892E853F859B8B8A8B998F888F3F8B74 +:205B60002E8BA5D1882309F0A5CF80E0DF91CF911F910F91FF90EF90DF90CF90BF90AF90F4 +:205B80009F908F900895F5011089C50161E0E7D9EC01009709F0BECFE8CF81E298E2998B02 +:205BA000888B80E098E09F878E8720E038E081E298E2D1CF2F923F924F925F926F927F92B4 +:205BC0008F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7C454D04094 +:205BE0000FB6F894DEBF0FBECDBF2C013B018E010E5B1F4FD80111965C934E9325962FAFA6 +:205C000025971C861F861FA21AA66115710509F45FC0FC018381882309F05AC0CA01DA0193 +:205C20002C912F3209F470C073013CE0832E912C8C0E9D1E64015E010894A11CB11C27E2D3 +:205C4000222E312C2C0E3D1EB501A80181DA882369F1D801ED91FC91119780818F3241F4C0 +:205C60003196D8011196FC93EE9381918F32C9F3882309F46FC0C601B701A50121E0CDDE96 +:205C80008823A1F0E614F70421F0C7011DDDF7011382C814D904C9F076016401D8018D912E +:205CA0009C91B501A80154DA882399F600E08AA5882321F0CE01879607DD1AA68F858823D6 +:205CC00041F0CE010C9600DD04C061017401E6CF00E0802FCC5BDF4F0FB6F894DEBF0FBE56 +:205CE000CDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F9043 +:205D00004F903F902F9008959A012F5F3F4FC901F80131832083D9014C912F5F3F4F4F3254 +:205D2000B1F3F30123812250223008F47DCF87E2E82EF12CEC0EFD1ED30159966D917C919C +:205D40005A97C70145DA882309F4B0CFF801808191816BCFC201B701A50125962FAD25978A +:205D60005CDE082FA4CFFB01242F6091183670911936AF011FCF0F931F93CF93DF93EC01AE +:205D8000662399F08C010E5D1F4F1093193600931836C801E7DCBE016C5F7F4FC80118DA19 +:205DA000DF91CF911F910F9108958C010E5D1F4FF0CFDF92EF92FF920F931F93DF93CF9356 +:205DC000CDB7DEB76C970FB6F894DEBF0FBECDBFFB01D42E19821C8220812F3229F122E209 +:205DE000E22EF12CE80EF91E8E010F5F1F4FC801B701AF0121E0DEDE8823F1F08C818230C5 +:205E000070F1D701F8018BE101900D928150E1F7DD2021F0F0921936E092183621E0C801A2 +:205E20002C8FA0DC2C8D0CC021812223C1F6642FA2DF282F8C8102C08C8120E0882389F499 +:205E4000822F6C960FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90089520E00E +:205E6000EDCF8E010F5F1F4FDACF0F931F93CF93DF938C010E942425882331F480E0DF9112 +:205E8000CF911F910F910895E8012496CE01B80141E0CDD3882321F0C80161E06CDFEFCFFA +:205EA000CE01B80140E0C3D3882341F3F5CF80912438882311F481E0089540911E365091E0 +:205EC0001F366091203670912136809122389091233822E236E30E944026882321F1409134 +:205EE0002538509126386091273870912838411551056105710521F41092243881E00895BC +:205F0000809122389091233822E236E30E944026882359F010922538109226381092273881 +:205F200010922838E9CF80E0089580E00895DF92EF92FF920F931F937B018C01D42E8091BA +:205F40001E3690911F36A0912036B09121368E159F05A007B107F1F0AADF882339F480E010 +:205F60001F910F91FF90EF90DF9008958091223890912338B801A70122E236E30E94F42498 +:205F8000882369F3E0921E36F0921F360093203610932136DD2049F081E0809324381F91C4 +:205FA0000F91FF90EF90DF90089581E01F910F91FF90EF90DF900895CF92DF92EF92FF9278 +:205FC0000F931F93CF93DF93EC017A018B01690189859A85AB85BC850196A11DB11D8417DF +:205FE0009507A607B70730F0EF89E03169F0E03209F445C080E0DF91CF911F910F91FF9075 +:20600000EF90DF90CF9008959927872F762F652F2B893C894D895E89620F731F841F951F57 +:2060200020911E3630911F364091203650912136621773078407950729F040E078DF882391 +:20604000C9F2EF89E03169F18FE790E0A0E0B0E0E822F9220A231B23F701EE0FFF1FEE0F0C +:20606000FF1FEE5DF94C80819181A281B381BF70F60180839183A283B38381E0BCCFCB01B8 +:20608000BA0127E096958795779567952A95D1F72B893C894D895E89620F731F841F951FD8 +:2060A000BFCF8FEF90E0A0E0B0E0E822F9220A231B23F701EE0FFF1FEE5DF94C808191810E +:2060C000A0E0B0E0F60180839183A283B38381E092CF4F925F926F927F928F929F92AF920E +:2060E000BF92CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB7DEB78C0149835A8354 +:206100006B837C832901842F952FA62FB72FAC01BD01CC24DD2476015E010894A11CB11CDE +:20612000612CE2E07E2E812C912CC801950144DF882309F447C0D401C301F801058404C0EA +:20614000880F991FAA1FBB1F0A94D2F7C80ED91EEA1EFB1E49815A816B817C8187898031A9 +:2061600019F1483F8FEF58078FEF68078FE07807E0F2F201C082D182E282F38281E00F90A3 +:206180000F900F900F90CF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F903B +:2061A0006F905F904F900895483FFFEF5F07F0E06F07F0E07F07E8F6C8019501FDDE88233B +:2061C00009F0B9CF80E0DBCF4F925F926F927F928F929F92AF92BF92CF92DF92EF92FF9288 +:2061E0000F931F93CF93DF93EC016A017B0128013901423051056105710590F089859A85EF +:20620000AB85BC850196A11DB11D84179507A607B70730F08F89803109F456C0803291F019 +:2062200080E0DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F9029 +:206240004F9008954A015B0117E0B694A794979487941A95D1F78B899C89AD89BE89880E96 +:20626000991EAA1EBB1EC501B40141E060DE8823B9F28F898031A9F18FE790E0A0E0B0E03D +:20628000C822D922EA22FB22F601EE0FFF1FEE0FFF1FEE5DF94C40825182628273828A89B2 +:2062A000823078F18D819E81AF81B885880D991DAA1DBB1D8093253890932638A0932738BC +:2062C000B093283881E0ADCF852E962EA72EBB248B899C89AD89BE89880E991EAA1EBB1E6F +:2062E000C2CF8FEF90E0A0E0B0E0C822D922EA22FB22F601EE0FFF1FEE5DF94C51824082CA +:20630000CECF81E08ECF2F923F924F925F926F927F928F929F92AF92BF92CF92DF92EF9275 +:20632000FF920F931F93DF93CF93CDB7DEB767970FB6F894DEBF0FBECDBF1C0149875A8778 +:206340006B877C873E872D87FC0181859285A385B4859C01AD012F5F3F4F4F4F5F4F2D83F1 +:206360003E834F835887ED85FE854080518062807380411451046104710409F4BEC00894B5 +:20638000411C511C611C711C1F860097A105B10509F454C0D301C201CC24DD2476018E01F2 +:2063A0000F5F1F4F4C8A5D8A6E8A7F8A2EC04C015D01C101B501A4019801FEDD882309F471 +:2063C0003DC089819A81AB81BC810097A105B10509F44EC0A50194012F5F3F4F4F4F5F4F91 +:2063E0002C8B3D8B4E8B5F8BDA01C9010894C11CD11CE11CF11CF101218532854385548556 +:20640000C216D306E406F506C8F44D805E806F807884481659066A067B0648F682E0882E90 +:20642000912CA12CB12C8C8A9D8AAE8ABF8AC101B501A4019801C0DD882319F680E06796CD +:206440000FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F903C +:206460008F907F906F905F904F903F902F900895D501C4010196A11DB11D2C013D012C8918 +:206480003D894E895F89421A530A640A750A29853A854B855C85421653066406750609F024 +:2064A000A5CF4C885D886E887F88C101B501A4010FEF1FEF2FEF3FE087DE882309F4BECFB2 +:2064C000481459046A047B0458F59501840107C0970186014C145D046E047F0408F56801AC +:2064E00079010894C108D108E108F108C101B701A6016ADE882361F7A1CFF10140805180A3 +:2065000062807380F1E0FF8729853A854B855C85213031054105510509F437CF1F8635CF62 +:20652000AD85BE854D915D916D917C9113974115510561057105C1F4ED85FE85408251829E +:2065400062827382FF85FF2369F00894411C511C611C711CD1014D925D926D927C9213979C +:2065600081E06DCF81E06BCFC101930182012CDE882311F763CFAF92BF92CF92DF92EF9236 +:20658000FF920F931F93DF93CF9300D000D0CDB7DEB76C017A018B0182E090E0A0E0B0E033 +:2065A000F60180839183A283B3835E010894A11CB11CC601B801A7019501FEDC882339F180 +:2065C000C601B801A70100E010E09801FDDD8823F1F0E980FA800B811C81F6018789803100 +:2065E00059F088EFE8168FEFF8068FEF08078FE01807F8F281E00CC0F8EFEF16FFEFFF0650 +:20660000F0E00F07F0E01F07A0F281E001C080E00F900F900F900F90CF91DF911F910F91EE +:20662000FF90EF90DF90CF90BF90AF9008956F927F928F929F92AF92BF92DF92EF92FF92DA +:206640000F931F93CF93DF93EC01142F70932338609322381F8A82E090E0A0E0B0E08883A1 +:206660009983AA83BB8310922438109225381092263810922738109228388FEF9FEFDC01AA +:2066800080931E3690931F36A0932036B0932136442309F444C0453078F080E0DF91CF9183 +:2066A0001F910F91FF90EF90DF90BF90AF909F908F907F906F90089560E070E0CB0140E00A +:2066C00036DC882351F3212F30E022953295307F3227207F32272E5E394CF901E254FE4F4D +:2066E000808190E08F7790700097B9F6F901E653FE4F80819181A281B38184369105A105FD +:20670000B10558F22A533E4FF901E080F18002811381E114F1040105110521F4BECFEE24D3 +:20672000FF248701C801B70140E001DC882309F4B4CF80912D3690912E36F2E080309F07E4 +:2067400009F0ABCF20913236222309F4A6CF8091303690913136009709F49FCF60912F369F +:20676000662309F49ACF2A8B6C831D8670E080E090E041E050E008C0282F2F5F2D8701967A +:206780008930910509F489CFD82E9A01082E02C0220F331F0A94E2F72617370769F76091F6 +:2067A0003836709139366115710509F47FC080E090E06D837E838F8398878090303690904B +:2067C0003136AA24BB248E0C9F1CA01EB11E8B8A9C8AAD8ABE8A6090333670903436798E3F +:2067E000688E2091323630E040E050E00E94893D680D791D8A1D9B1D6A8F7B8F8C8F9D8F0E +:206800009301220F331F22953295307F3227207F322721503E4F232F3327269540E050E02E +:20682000260F371F481F591F2E873F87488B598B8091353690913636009709F440C0A0E09F +:20684000B0E0E21AF30A040B150BE80EF91E0A1F1B1F04C016950795F794E794DA94D2F7C8 +:20686000E986FA860B871C8725EFE2162FE0F20620E0020720E0120758F185EFE8168FEF86 +:20688000F80680E0080780E0180730F180914E3690914F36A0915036B09151368A8F9B8FEE +:2068A000AC8FBD8F80E28F8B81E0F8CE609146367091473680914836909149367ACF80913A +:2068C000423690914336A0914436B0914536B9CF8CE08F8B80E0E2CE80E18F8B81E0DECE99 +:2068E000CF93DF93DC01CD91DC9111971C161D06DCF41296E0E0F0E020E030E0A901542FDA +:20690000432F322F22276D9170E080E090E0262B372B482B592B3196EC17FD0781F7B90193 +:20692000CA01DF91CF91089520E030E0A901F7CFCF93DF93FB01DC012D913C91B9016E5FE0 +:206940007F4FEC01C60FD71FE60FF71FD9011196A40FB51F2115310599F0215030408A91AD +:2069600092914115510519F06C91862396231197891781F320E030E0C901DF91CF910895DD +:2069800021E030E0C901DF91CF910895CF93DF93FB0120813181DC012D933C93A081B181CD +:2069A000109701F1BD01615070401296EA0FFB1FEA01CA0FDB1FA80FB91F80E09A912291D9 +:2069C00030E0290F311D280F311D81E02F3F310509F008F480E02E93615070409FEF6F3FE4 +:2069E000790761F7DF91CF910895EF92FF920F931F93CF93DF938B01FC0171836083611542 +:206A0000710581F022E0E22EF12CE80EF91EC0E0D0E0C7018C0F9D1F0E944D3D2196C0172A +:206A2000D107B9F7DF91CF911F910F91FF90EF90089524E030E0FC013783268384E090E0BB +:206A4000089521E0FC01208380E090E00895EF92FF920F931F93DF93CF930F92CDB7DEB797 +:206A60007C018E010F5F1F4FC8010E944D3D89818823D1F7F7011782168280E090E00F9024 +:206A8000CF91DF911F910F91FF90EF9008950F931F93DF93CF930F92CDB7DEB78C01CE01ED +:206AA0000196FBD78981823070F085E090E0F8019783868325E030E0C9010F90CF91DF9112 +:206AC0001F910F910895F8019181933141F0882369F481E0F801828720E030E0EDCF8823E7 +:206AE00059F481E0818720E030E0E6CF86E0F801828720E030E0E0CF8DE0F801818720E086 +:206B000030E0DACF0B96C9D780E090E00895CF93DF93EC016C897D898E559F4F66DF6C8947 +:206B20007D89CE018B539F4F60DF80E090E0DF91CF910895FC016489758981589F4F55DF55 +:206B400080E090E008950F931F93CF93DF938C01EC016696CE0164E070E047DFCE01C0DE34 +:206B6000F801648775878687978780E090E0DF91CF911F910F9108950F931F93CF93DF9355 +:206B80008C01EC016696CE0164E070E02EDFCE01A7DEF801608B718B828B938B695F7F4F1A +:206BA0008F4F9F4F28E030E040E050E00E94DE3DF801358B248B2132310564F086E090E0C9 +:206BC0009783868326E030E0C901DF91CF911F910F91089520E030E0C901DF91CF911F919B +:206BE0000F910895BC0181E090E02BD780E090E060E070E026D780E090E061E070E021C722 +:206C00004F925F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93A0 +:206C2000EC01F62E662309F4A4C08881861709F4EEC06730C1F06E30C1F48D30B1F005E02A +:206C400010E0C801DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F9095 +:206C60005F904F900895863051F700E010E0A8E0AA2EFCE0CF2EEEE06E2E7FE0B72E62E0B2 +:206C8000E62E992493945AE0752E45E0D42E37E0832E23E0422E99E0592EF81691F2873075 +:206CA00009F495C08830A8F4833009F453C0843008F03CC08130A1F1823008F454C08F2D02 +:206CC000893008F49EC081E090E08CDF58828881E4CF8B3059F08C3078F4893009F467C0C6 +:206CE0008A3008F47DC09F2D9B3089F081E090E079DFC8828881D1CF8D3009F452C08D30EC +:206D000000F18E3009F075C09F2D9B30E9F480E090E068DFF8828881C0CF8F2D813019F182 +:206D200081E090E05FDFE8828881B7CF853009F444C0863090F081E090E054DF8882888148 +:206D4000ACCF8F2D8D3019F381E090E04BDFB8828881A3CF9F2D9430D1F281E090E042DF3E +:206D6000D88288819ACF80E090E03CDF9882888194CF81E090E036DF00E010E080E090E050 +:206D800060E070E05ED680E090E061E070E059D60F5F1F4F0530110589F7188200E010E08E +:206DA00050CF81E090E01EDF6882888176CF80E090E018DF7882888170CF8F2D863009F436 +:206DC000A6CF81E090E00EDFA882888166CF9F2D943009F49CCF81E090E004DFA882F5CF7E +:206DE0008F2D813009F493CF81E090E0FBDEE8829BCF8F3009F491CFF88205E010E08881D5 +:206E00004CCF80E090E0EEDE4882888146CF863049F08D3009F029CF81E090E0E3DE8EE036 +:206E2000888323CF81E090E0DDDE87E088831DCFCF92DF92EF92FF920F931F93CF93DF935F +:206E4000EC018C010A5E1F4FC80161E070E0CDDDC88CC80161E070E0C8DDD88CC80164E01A +:206E600070E0C3DDC8013CDD7B018C0188858C1521F0CE0108966C2DC3DEC801B70123D657 +:206E800088858D1521F0CE0108966D2DB9DE80E090E0DF91CF911F910F91FF90EF90DF9027 +:206EA000CF9008950F931F93DF93CF930F92CDB7DEB78C01CE010196F0D5C80108966981EB +:206EC0009FDE9C01009719F0F80197838683C9010F90CF91DF911F910F9108954F925F92E4 +:206EE0006F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93CF93DF935B016C01C7 +:206F0000FA0138012115310509F481C080819181D90111969C938E93808191818C010E5FA2 +:206F20001F4F020F131FA114B104C104D10409F45DC022E0422E512C480E591E4E0E5F1EED +:206F40000CC00115110519F0D8019E928D01A114B104C104D10409F449C0F20182902F015A +:206F6000EE24FF2499240894A108B108C108D1086114710429F0A114B104C104D10481F106 +:206F8000C82DD0E0BE016170707082E090E059D580E090E060E070E054D50115110549F0EE +:206FA0008ED590E00E2C02C0880F991F0A94E2F7982A80E090E061E070E043D5A114B10497 +:206FC000C104D10409F4BDCF0894E11CF11CF8E0EF16F10409F4B5CFD595C7958C2EC3CF83 +:206FE00081E090E061E070E02CD5CACFDF91CF911F910F91FF90EF90DF90CF90BF90AF900B +:207000009F908F907F906F905F904F9008958081918100E010E087CF2F923F924F925F920C +:207020006F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB735 +:2070400028970FB6F894DEBF0FBECDBF3C01962E29833A834B835C831E830D8317012601A3 +:20706000B886AF82A9A051E0C52ED12C681509F487C029813A814B815C81211531054105B6 +:20708000510529F58D8D9E8DAF8DB8A10097A105B10509F097C020E030E0C90128960FB602 +:2070A000F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F9076 +:2070C0007F906F905F904F903F902F900895BB24EE24FF24C301692D93DD69817A818B81DA +:2070E0009C814D815E8191018601F8DE4114510461F0C201B1014F8158851ADC41E0E42E91 +:20710000F12C009711F0EE24FF24C114D104E9F0D3018C918F5F8C93E114F10459F02D8D17 +:207120003E8D4F8D58A1211531054105510511F0BA1448F1C301682D63DD8D8D9E8DAF8D85 +:20714000B8A10097A105B10591F4E114F10409F4A2CFB3948B2D81508A1508F4BBCFAA2047 +:2071600019F0AB1408F439C022E030E096CFC30161E046DD6D8D7E8D8F8D98A1A4D4E5CF2D +:20718000CC24DD2476CFC30166E03ADDC30164E037DD8D8D9E8DAF8DB8A1B595A7959795F0 +:2071A0008795B595A795979587952D8D3E8D4F8D58A1280F391F4A1F5B1F2D8F3E8F4F8FB2 +:2071C00058A3BBCFC30161E01BDD6D8D7E8D8F8D98A179D420E030E060CF23E030E05DCF08 +:2071E0008F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC018C010A5E1F4F6C898B +:207200007D89C801F2DB00D000D00F92288939894A895B89ECE5EE2EF12CEC0EFD1E79E3EC +:20722000C72ED12CCC0EDD1E6FE7A62EB12CAC0EBD1E8C859D85AE85BF85EDB7FEB78183E4 +:207240009283A383B4838B858583CE01089664E08A84E2DE9C010F900F900F900F900F906D +:20726000009711F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F90D0 +:2072800008958F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC018C010A5E1F4F42 +:2072A000C80162E070E0A1DBC8011ADB6B017C01695F7F4F8F4F9F4F28E030E040E050E086 +:2072C0007DD4213231058CF026E030E03F832E83C901DF91CF911F910F91FF90EF90DF9068 +:2072E000CF90BF90AF908F900895C801B9017DDB00D000D00F928C859D85AE85BF85EDB77B +:20730000FEB781839283A383B4831582CE0108966BE0A7019601EE24FF24CC24DD24AA24C0 +:20732000BB24898479DE9C010F900F900F900F900F90009769F2CACF6F927F928F92AF9253 +:20734000BF92CF92DF92EF92FF920F931F93DF93CF930F92CDB7DEB73C01CE0101969DD303 +:2073600083010A5E1F4F298130E040E050E0295F3F4F4F4F5F4FF3E0559547953795279526 +:20738000FA95D1F7C801B90130DB00D000D00F92298130E040E050E0F30184859585A6857B +:2073A000B785EDB7FEB781839283A383B4831582C30108966BE0EE24FF24CC24DD24AA248A +:2073C000BB24F301818428DE9C010F900F900F900F900F90009719F0F30197838683C90196 +:2073E0000F90CF91DF911F910F91FF90EF90DF90CF90BF90AF908F907F906F9008952F92D9 +:207400003F924F925F926F927F928F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93F8 +:2074200000D0CDB7DEB79A8389831A012B013901C801B901DADAC114D10419F0C601B30154 +:20744000D4DA00D000D00F928E899F89A88DB98DEDB7FEB781839283A383B4838A8D858395 +:2074600089819A8164E0A2019101D6DD0F900F900F900F900F900F900F90CF91DF911F91E2 +:207480000F91FF90EF90DF90CF90BF90AF908F907F906F905F904F903F902F9008958F929B +:2074A000AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC0189818131D9F114E0812E18 +:2074C00000D000D00F92488959896A897B892C893D898E010A5E1F4FBCE5EB2EF12CEC0E10 +:2074E000FD1EA9E3CA2ED12CCC0EDD1EEDB7FEB711821282138214821582CE010896AA249E +:20750000BB247DDF9C010F900F900F900F900F90009711F09F838E83C901DF91CF911F9163 +:207520000F91FF90EF90DF90CF90BF90AF908F9008958A84C5CF8F92AF92BF92CF92DF925E +:20754000EF92FF920F931F93CF93DF93EC0189818E30A9F104E0802E00D000D00F924889FE +:2075600059896A897B892C893D898E010A5E1F4FEDB7FEB711821282138214821582CE0141 +:207580000896EE24FF24CC24DD24AA24BB2437DF9C010F900F900F900F900F90009711F014 +:2075A0009F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F9008958A847A +:2075C000CBCF8F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC0100D000D00F9224 +:2075E000488959896A897B892C893D898C010A5E1F4FECE5EE2EF12CE80EF91E99E3C92E79 +:20760000D12CCC0EDD1E8FE7A82EB12CAC0EBD1E8C859D85AE85BF85EDB7FEB781839283BE +:20762000A383B4838B858583CE0108968A84E7DE9C010F900F900F900F900F90009711F045 +:207640009F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F900895CF9286 +:20766000DF92EF92FF920F931F93CF93DF938C016B017901B8018AD9E60128813981F7018E +:20768000A081B181AD014150504057FD38C0FD013296EE0DFF1D1196A00FB11F60E010E049 +:2076A0008291882329F1EC9001E00AC0762F660F7123B1F0E02A959587958823C1F0000FC1 +:2076C00090E080FFF8CF662389F721503040B601620F731FEB011A8162E071E0712351F75A +:2076E000702F7095E72295958795882341F7EC924150504011978FEF4F3F580789F6DF9113 +:20770000CF911F910F91FF90EF90DF90CF9008952F923F924F925F926F927F928F929F9278 +:20772000AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB761970FB6F894DEBFAC +:207740000FBECDBF3C01B6E14B2E512C480E591EFC0164897589C20148D9C30108969D83EB +:207760008C83F301E45AFF4FFF83EE83C301C99699878887AFE72A2E312C260C371C00D095 +:2077800000D00F92F301208931894289538984859585A685B785EDB7FEB781839283A38358 +:2077A000B483F3018385EDB7FEB785838C819D8164E08201EE80FF80C884D9845101F30167 +:2077C00082842ADC9B838A830F900F900F900F900F90009709F087C0C3018B539F4F9D87CC +:2077E0008C87FC0140815181141615060CF09DC0E0E0F0E060E000E010E0E60DF71DE95365 +:20780000FF4F8081882351F090E09C0121703070020F131F959587958823B1F76F5FE62F30 +:20782000F0E0E417F5074CF3CE01019636D1222717FD2095322F095F1F4F2F4F3F4FE3E0BD +:207840003595279517950795EA95D1F71F870E879924C30188519F4F9B878A87F301EE5526 +:20786000FF4FF98BE88B8981981608F043C08A859B856E857F85B9D8C2016A857B854889D6 +:2078800059892C853D85EBDE00D000D00F92F301208931894289538984859585A685B78501 +:2078A000EDB7FEB781839283A383B483F3018385EDB7FEB785838C819D8164E08201EE803C +:2078C000FF80C884D9845101F3018284A5DB0F900F900F900F900F90009739F493948981A4 +:2078E000981640F4C4CF8A819B81F301978386839B838A838A819B8161960FB6F894DEBF9E +:207900000FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F9028 +:207920005F904F903F902F90089500E010E07CCFCF93DF93EC01188219821A821B821C8266 +:207940001D821F821E821B86188681E089878A87188A198A1A8A1B8A1D8A1C8A1C861D8666 +:207960001E861F86CE01089660E04AD98E839F83DF91CF910895CF93DF93EC012E813F811E +:207980002115310519F48881882321F0C901DF91CF910895CE01019680D08A819B81AC8168 +:2079A000BD810196A11DB11D8A839B83AC83BD83E981E83150F084E090E09F838E8324E0FE +:2079C00030E0C901DF91CF910895F0E0EE0FFF1FEA5CFC4F0190F081E02DCE0109952E81B9 +:2079E0003F81D4CF0F931F93DF93CF93CDB7DEB7CB50D1400FB6F894DEBF0FBECDBF8E01E1 +:207A00000F5F1F4FC80194DF2F8138852115310569F0C901C55FDE4F0FB6F894DEBF0FBE46 +:207A2000CDBFCF91DF911F910F9108958981882381F7C801A0DF2F81388521153105B1F30B +:207A4000E8CF8130910551F08230910561F0009721F46115710571F44298089561157105EE +:207A600039F0439A08956115710531F0459A089543980895429A08954598089580E090E09F +:207A800060E070E0DEDF80E090E061E070E0D9CF90932A38809329380895CF93DF93EC0139 +:207AA000E0912938F0912A38309729F009958883DF91CF9108951882DF91CF91089581E0B3 +:207AC000349B80E00895AF92BF92CF92DF92EF92FF920F931F935B016C01161617061806E0 +:207AE000190674F4EE24FF248701C8DF0894E11CF11C011D111DEA14FB040C051D05ACF3DA +:207B00001F910F91FF90EF90DF90CF90BF90AF900895629FD001739FF001829FE00DF11D1D +:207B2000649FE00DF11D929FF00D839FF00D749FF00D659FF00D9927729FB00DE11DF91F45 +:207B4000639FB00DE11DF91FBD01CF0111240895AA1BBB1B51E107C0AA1FBB1FA617B7073E +:207B600010F0A61BB70B881F991F5A95A9F780959095BC01CD010895A1E21A2EAA1BBB1BCC +:207B8000FD010DC0AA1FBB1FEE1FFF1FA217B307E407F50720F0A21BB30BE40BF50B661FF3 +:207BA000771F881F991F1A9469F760957095809590959B01AC01BD01CF01089597FB092E51 +:207BC00005260ED057FD04D0D7DF0AD0001C38F450954095309521953F4F4F4F5F4F0895F0 +:207BE000F6F790958095709561957F4F8F4F9F4F08950790F691E02D09949111089581564E +:207C00008A5108F4805285580895FB01DC0105900D920020E1F70895FC0105900020E9F70D +:207C2000809590958E0F9F1F0895FB01DC0104C08D910190801921F441505040C8F7881B95 +:207C4000990B0895FB01DC0102C001900D9241505040D8F70895FB01DC014150504030F071 +:207C60008D910190801919F40020B9F7881B990B0895FB01DC014150504048F001900D9299 +:207C80000020C9F701C01D9241505040E0F708950F931F93DF93CF93CDB7DEB72E970FB634 +:207CA000F894DEBF0FBECDBF0D891E898F89988D26E02C831A83098397FF02C080E090E8BA +:207CC00001979E838D839E01255E3F4FCE010196698D7A8DA90119D04D815E8157FD0AC06A +:207CE0002F813885421753070CF49A01020F131FF80110822E960FB6F894DEBF0FBECDBFF0 +:207D0000CF91DF911F910F9108952F923F924F925F926F927F928F929F92AF92BF92CF92EB +:207D2000DF92EF92FF920F931F93DF93CF93CDB7DEB72C970FB6F894DEBF0FBECDBF6C0108 +:207D40001B018A01FC0117821682838181FFC4C12E010894411C511CF6019381F10193FD23 +:207D6000859193FF81911F01882309F4B1C1853239F493FD859193FF81911F01853221F4F5 +:207D800090E0B601F5D1E8CFEE24FF2420E02032B0F48B3269F08C3228F4803251F083327C +:207DA00071F40BC08D3239F0803349F421602CC02260246029C0286027C0206125C027FD66 +:207DC0002CC0382F30533A3098F426FF08C08E2D880FE82EEE0CEE0CE80EE30E15C08F2D16 +:207DE000880FF82EFF0CFF0CF80EF30E20620CC08E3221F426FD6CC1206406C08C3611F425 +:207E0000206802C0883649F4F10193FD859193FF81911F01882309F0BACF982F9554933021 +:207E200018F09052933028F40C5F1F4FFFE3F9830DC0833631F0833771F0833509F05CC0B3 +:207E400021C0F801808189830E5F1F4F420171E0A72EB12C15C062E0662E712C600E711ED5 +:207E6000F8018080918026FF03C06E2D70E002C06FEF7FEFC4012C8770D15C0183012C854C +:207E80002F7716C052E0652E712C600E711EF8018080918026FF03C06E2D70E002C06FEF0A +:207EA0007FEFC4012C874ED15C012C852068830123FD1EC007C080E290E0B6012C8758D179 +:207EC000FA942C858F2D90E0A816B906A0F310C0F40127FD859127FF81914F0190E0B60179 +:207EE0002C8746D12C85F110FA940894A108B108A114B10469F7E9C0843611F0893641F557 +:207F000027FF08C0F80160817181828193810C5F1F4F09C0F80160817181882777FD8095EA +:207F2000982F0E5F1F4F4FE6B42EB22297FF09C090958095709561957F4F8F4F9F4FF0E8AE +:207F4000BF2AA2012AE030E03FD1782E741844C0853731F43FEEB32EB2222AE030E025C073 +:207F600099EFB92EB2228F36C1F0803720F4883509F0AEC00DC0803721F0883709F0A8C0A4 +:207F800002C020E1B22AB4FE0BC084E0B82A08C0B4FE09C0E6E0BE2A06C028E030E005C0EB +:207FA00020E130E002C020E132E0B7FE08C0F80160817181828193810C5F1F4F07C0F801E2 +:207FC0006081718180E090E00E5F1F4FA201FCD0782E7418FFE7BF22B6FE0BC02EEFB2224B +:207FE0007E1438F4B4FE07C0B2FC05C08FEEB82202C0A72C01C0AE2C8B2D90E0B4FE0DC0A9 +:20800000FE01E70DF11D2081203319F4E9EEBE2209C0A394B2FE06C004C0867890700097D8 +:2080200009F0A3948B2C9924B3FC13C0B0FE0EC0AF1428F4E72CEF0CEA18AF2C07C0E72CFA +:2080400005C080E290E0B60193D0A394AF14C8F304C0AF1410F4FA1801C0FF2484FE0EC0E9 +:2080600080E390E0B60184D082FE1DC081FE03C088E590E010C088E790E00DC0C401867867 +:208080009070009781F081FC02C080E201C08BE2B7FC8DE290E0B6016BD005C080E390E0ED +:2080A000B60166D0EA947E14C8F37A94F201E70DF11D808190E0B6015BD07720B1F705C0AE +:2080C00080E290E0B60154D0FA94FF20C9F744CEF6012681378102C02FEF3FEFC9012C9684 +:2080E0000FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F9080 +:208100008F907F906F905F904F903F902F900895F999FECF92BD81BDF89A992780B5089529 +:20812000262FF999FECF92BD81BDF89A019700B4021639F01FBA20BD0FB6F894FA9AF99AB1 +:208140000FBE0895FC010590615070400110D8F7809590958E0F9F1F0895FC016150704052 +:2081600001900110D8F7809590958E0F9F1F08950F931F93CF93DF938C01EB018B8181FF2F +:208180001BC082FF0DC02E813F818C819D812817390764F4E881F9810193F983E88306C021 +:2081A000E885F985802F0995009731F48E819F8101969F838E8302C00FEF1FEFC801DF91CB +:2081C000CF911F910F910895FA01AA27283051F1203181F1E8946F936E7F6E5F7F4F8F4F45 +:2081E0009F4FAF4FB1E03ED0B4E03CD0670F781F891F9A1FA11D680F791F8A1F911DA11D04 +:208200006A0F711D811D911DA11D20D009F468943F912AE0269F11243019305D3193DEF622 +:20822000CF010895462F4770405D4193B3E00FD0C9F7F6CF462F4F70405D4A3318F0495D41 +:2082400031FD4052419302D0A9F7EACFB4E0A6959795879577956795BA95C9F70097610534 +:20826000710508959B01AC010A2E06945795479537952795BA95C9F7620F731F841F951F17 +:20828000A01D089518E000E0C8E9D8E040E005C022974109FE014BBFACDCCA39D1074007A8 +:2082A000B9F7F894FFCF2E2E0053656C656374204469736B006E6F20696D6167652066695E +:2082C0006C657320666F756E640001030507090E10121416181C1E696E636F6D706C65748E +:2082E000652077726974650062616420736563746F7220256420666F7220742564006275F3 +:2083000066206C6F636B65642025642F25643A256400636865636B73756D206661696C75BD +:208320007265203000636865636B73756D206661696C757265203100636865636B73756D17 +:20834000206661696C757265203200636865636B73756D206661696C006669726D776172BC +:20836000652E78766600524553554C543A2053554343455353004649524D57415245204502 +:2083800052524F522025640043504C44204669726D77617265202564002564002575005350 +:2083A000442072656164206572726F72205200424144204655534553202530325820253020 +:2083C000325820253032580043504C4420495320424C414E4B0057524F4E472043504C44DD +:2083E000202D2025640053454C462D54455354204F4B005344207265616420737461727495 +:20840000206572726F720053442072656164206572726F7220440077722077726F6E6720BB +:20842000747261636B2025642F25640052657665727465642074726B2025303264202020A9 +:208440000053442072656164206572726F7220570053442077726974655374617274206692 +:2084600061696C005344207772697465206572726F7200534420777269746553746F7020F2 +:208480006661696C0053617665642074726B202530326420696E20256C752020004E4F20B7 +:2084A000534420434152443F0043415244204552524F522025643A2564002530326400256C +:2084C000642000D5AAAD0000000000000000000000008A01AD01D8010D024E0221359A3556 +:2084E0009C39F038A335193519358235BC35E13A8735883B9B3A9B3A9B3A4F3A4F3A4F3AAF +:0C850000523747354735413927351837C9 +:020000040001F9 +:20EFF800DDDDDDDD0001000097C00000B2C00000B0C00000AEC00000ACC00000AAC0000007 +:20F01800A8C00000A6C00000A4C00000A2C00000A0C000009EC000009CC000009AC00000D0 +:20F0380098C0000096C0000094C0000092C0000090C000008EC000008CC000008AC0000030 +:20F0580088C0000086C0000084C0000082C0000080C000007EC000007CC000007AC0000090 +:20F0780078C0000076C0000074C0000072C0000070C000001E051E1F150A0E11111F110E87 +:20F098001F15151F05050E151D1F041F111F1108100F1F041B1F10101F061F1F0E1F0E11D0 +:20F0B8000E1F05020010001F0D16121509011F010F101F0718071F0C1F000000031C030091 +:20F0D8000A004552524F525A58464C41534858495358454D5054590046454D555142494E32 +:08F0F800584E4F5458464F5585 +:20F100004E4400464C415348494E475846454D555142494E5851515100464C4F50505958E5 +:20F12000454D5558424F4F544C4F41444552000011241FBECFEFD0E4DEBFCDBF11E0A0E087 +:20F14000B1E0E8EEFFEF01E00BBF02C007900D92AA30B107D9F712E0AAE0B1E001C01D92D8 +:20F16000A733B107E1F7DBD03DC74ACF249A259A279A2E9A089588EC3197319731970000EE +:20F180008A95D1F7089502D02C9801C02C9A8FEF98E087FD2D9A87FF2D98880F1E998395DC +:20F1A0002F9A2F989A95A9F70895FB018BBF83E080935700E8958091570080FDFCCF81E1B1 +:20F1C00080935700E89508950F921F928BBFFB01DA0190E80D901D9081E080935700E8952E +:20F1E00032969A95B9F7FB0185E080935700E8958091570080FDFCCF81E180935700E89527 +:20F200001F900F9008955E9808955E9A0895A1E0B0E0ECE0F9EFB8C68983B8DF2A98898129 +:20F22000B7DF2A9A2196E2E0CBC6A2E0B0E0EAE1F9EFAAC66A838983E6DF89818068E7DFBF +:20F240006A81862F8064E3DF2296E2E0B9C6CF93DF93DBDFC8EFD1E080E0D9DF2197E1F7D1 +:20F26000DF91CF910895EF92FF920F931F93CF93DF938C01CADF1FC023E0829FC0011124B8 +:20F280000F5F1F4FEC01C753D0412CECE22E2FEEF22EE80EF91ECE01AA2797FDA095BA2FB6 +:20F2A000ABBFFC018791880FB2DF2196CE15DF0591F780E0ACDFC801AA2797FDA095BA2F6A +:20F2C000ABBFFC0187918823B9F6CDB7DEB7E6E073C61F93209A229A569A48DF2A98289A7A +:20F2E00018EC49DF1150E9F7289818EC44DF1150E9F7289A18EC3FDF1150E9F784DF81E28E +:20F3000086DF8FEB84DF84E182DF80E280DF8CE07EDF80E060E089DF9ADF1F910895A2E00B +:20F32000B0E0E4E9F9EF29C65C9A599A5A9A8FE493EC0197F1F700C00000499956C04C99AD +:20F3400054C0239AC6DF89E191EF8DDF80E062E06CDF8DE091E0A0D280E091E0ACD38823A9 +:20F3600009F03AC083E091EF7EDFEE24FF2487016E010894C11CD11C88E0B82EC801B701F9 +:20F3800014DF87E391E06FEF70E040E051E023D687E391E060E071E0A601ECD489819A81AF +:20F3A000009729F0C801B70147E351E00DDF85B18B2585B980E091E0A0E0B0E0E80EF91EC3 +:20F3C0000A1F1B1F90E0E91690EFF90691E0090790E0190799F603C080EF90EF44DF499B85 +:20F3E000FECF4C9BFCCF4A9BFACF80E090E0FC0125913491AFEF2F3F3A0711F0FC010995AF +:20F4000068DF80E060E011DF8AED90EF2CDFFFCFDF92EF92FF920F931F93182F042FF52ED2 +:20F42000E62ED72E87FF08C087E740E050E0BA01EFDF8230E0F41F77A6DE812FA9DE8D2D8D +:20F44000A7DE8E2DA5DE8F2DA3DE802FA1DE103421F0183421F081E003C085E901C087E80A +:20F4600097DE1AE094DE87FF02C01150D9F71F910F91FF90EF90DF900895A5E0B0E0E2E4ED +:20F48000FAEF7CC573DE04E676DE0150E9F70AE07DDE0150E9F780E440E050E0BA01B8DF06 +:20F4A000813009F067C088E44AEA51E060E070E0AFDF8130D1F58E010F5F1F4F45E0C42E93 +:20F4C000D12CCC0EDD1E780162DEF70181937F01EC15FD05C9F78B81813009F04BC08C8184 +:20F4E0008A3A09F047C008C046DE0894E108F108E114F10429F43EC030E1E32E37E2F32E7D +:20F5000089EE40E050E060E070E482DF882361F73DC03DDEF80181938F01EC15FD05C9F7B4 +:20F52000898186FF25C09CE026C089EE40E050E0BA016EDF823020F492E029EEE22E03C004 +:20F5400091E081E4E82E00E117E208C09D8313DE015010409D810115110561F08E2D40E0F5 +:20F5600050E0BA019D8354DF9D81882379F717C094E001C090E090930A019D8307DE81E004 +:20F580009D81911180E02596E8E014C58AE740E050E0BA013DDF882309F4BBCFEBCF80E506 +:20F5A00040E052E060E070E09D8332DF9D81882309F7E1CFA1E0B0E0EFEDFAEFDDC46C01DB +:20F5C000590180910A0183FD07C0E9E0440F551F661F771FEA95D1F781E51ADF882391F5EC +:20F5E00050E4E52E5CE9F52ED2DD8F3F39F40894E108F108E114F104B9F724C08E3F11F5E3 +:20F60000EE24FF24EA18FB0882E092E0E80EF91EE01AF10AA114B10429F0B9DD0894A1087C +:20F62000B108F8CFB4DDF60181936F0101501040C9F7ADDD0894E108F108E114F104C9F72B +:20F6400080E001C081E08983A1DD89812196EAE0AFC4CF93DF93C0910B01D0910C0162504F +:20F660007040804090402E813F81488559852250304040405040621773078407950780F4B0 +:20F680002A8130E040E050E02ED49B01AC018A899B89AC89BD89280F391F4A1F5B1F03C02D +:20F6A00020E030E0A901B901CA01DF91CF910895CF93DF93EC01E0910B01F0910C01198237 +:20F6C00018826C817D818E819F81613071058105910551F126813781408551856217730724 +:20F6E0008407950708F5611571058105910539F42081233021F466857785808991896887AF +:20F7000079878A879B87611571058105910511F0A0DF04C066857785808991896C877D8769 +:20F720008E879F8780E001C081E0DF91CF910895A4E0B0E0EDE9FBEF25C4DC01CB01E091C8 +:20F740000B01F0910C0182309105A105B10508F452C0268137814085518582179307A40785 +:20F76000B50708F048C02081223021F0233009F042C01CC0492F5A2F6B2F77270285138547 +:20F7800024853585400F511F621F731F9C013070220F331FCE01019602E010E00BDF8823A7 +:20F7A00051F529813A8140E050E029C0AC01BD0127E076956795579547952A95D1F7028516 +:20F7C000138524853585400F511F621F731F9C012F773070220F331F220F331FCE0101960D +:20F7E00004E010E0E7DE882331F429813A814B815C815F7004C021E030E040E050E0B901E4 +:20F80000CA012496E4E0DAC3A0E0B0E0E9E0FCEFB1C3F82EE92E5A016B012EEF31E002E0B6 +:20F8200010E0C8DE882369F58F2CE4014E019E2CE401888199812AEA8535920721F58F2D2F +:20F840009E2DB601A50126E330E0B4DE882331F48881998121E486349207B9F08F2D9E2D5A +:20F86000B601A50122E530E002E010E0A3DE882371F481E02881398191E42634390741F4A9 +:20F8800004C083E005C082E003C080E001C081E0CDB7DEB7ECE08AC3A8E2B0E0E1E5FCEFD8 +:20F8A00065C37C0110920C0110920B01009709F4F8C0E3DD80FDF7C06E010894C11CD11C31 +:20F8C000C60140E050E0BA019FDF8130C9F4C60140E050E0BA012EEB31E000E110E06ADE55 +:20F8E000882309F0E2C08D81882309F4E0C089849A84AB84BC84C601B501A40185DF03C089 +:20F90000882499245401833009F4CFC0882309F0CEC06E010894C11CD11CC601B501A401C1 +:20F920002DE030E004E210E045DE882309F0BDC0D60119966D917C911A9780E090E0611508 +:20F9400071058105910521F4688D798D8A8D9B8D2C8130E040E050E0C6D26DA37EA38FA3BE +:20F9600098A7F6014180528066247724480C591C6A1C7B1CD7011A964D925D926D927C9250 +:20F980001D97E9811296EC93D60114964D915C911597D70115965C934E931497D6011696A9 +:20F9A0006D917C91179780E090E0611571058105910521F46C897D898E899F8904E0569598 +:20F9C00047950A95E1F74A01AA24BB24D60111960D911C91129720E030E0601B710B820BD6 +:20F9E000930B2DA13EA14FA158A5621B730B840B950B681979098A099B092E2F30E040E0DE +:20FA000050E090D22E5F3F4F4F4F5F4FD70116962D933D934D935C931997273FBFE03B0713 +:20FA2000B0E04B07B0E05B0708F441C0273FEFEF3E07E0E04E07E0E05E0710F482E001C00B +:20FA400083E0D7018C93833029F488A199A1AAA1BBA108C08DA19EA1AFA1B8A5840D951D4D +:20FA6000A61DB71DF70186879787A08BB18B480C591C6A1C7B1C2DA13EA14FA158A5420E95 +:20FA8000531E641E751ED70152964D925D926D927C92559711961C921197F0920C01E0925B +:20FAA0000B0180E005C082E003C081E001C087E0A896E0E177C2ACE3B0E0E0E6FDEF54C248 +:20FAC000C0900B01D0900C01C114D10409F446C1F60111829E012F5F3F4F388B2F877C0174 +:20FAE000FC01208101962032D1F32F3209F47C01198A1A8A1B8A1C8AF7018081813240F46E +:20FB0000CE010D96D5DD1D8E882309F4F7C029C190E2892E8DE0482E512C4C0E5D1EBDE1D1 +:20FB20006B2E712C6C0E7D1EA8E22A2E312C2C0E3D1EEF85F889DF01CF010B9601C08D9280 +:20FB4000A817B907E1F790E0992428E0D701A90DB11D8C9193948132C0F08F32B1F08E32F4 +:20FB600011F0921738F0283081F48E3271F498E02BE0ECCF382F31563A3108F48052DF017C +:20FB8000A90FB11D8C939F5FE1CF91E0813208F090E09387C2018CDD882309F086C0498D80 +:20FBA0005A8D6B8D7C8D2D853E852F703070F5E0220F331FFA95E1F7C30100E210E0FADC7E +:20FBC000882309F0D1C08D8D882309F4CFC088A583FD0BC0F301AF85B889E215F30509F4D2 +:20FBE0006EC091918D919817C1F3A0900B01B0900C010D851E850F5F1F4F09F4B7C0898D10 +:20FC00009A8DAB8DBC8D0097A105B10509F4AEC098012F7030702115310509F043C0019607 +:20FC2000A11DB11D898F9A8FAB8FBC8F6D897E898F89988D611571058105910541F4F50105 +:20FC4000848195810817190708F090C02BC0F501228130E021503040A801E4E05695479559 +:20FC6000EA95E1F72423352321153105D9F460DD623071058105910508F476C0F501268125 +:20FC8000378140855185621773078407950708F06DC06D8B7E8B8F8B988FDBDC698F7A8FD8 +:20FCA0008B8F9C8F1E870D877ACF833009F059C0EF85F8899385992309F45AC052C0EF8552 +:20FCC000F88983858823D1F488A584FF51C0E90CF11CF30184899589A0E0B0E0DC0199279C +:20FCE0008827228D338D40E050E0822B932BA42BB52B898B9A8BAB8BBC8B1BCF8D8D882317 +:20FD000079F188A584FD2CC0BE01635E7F4FFB0184899589A0E0B0E0DC0199278827228D5F +:20FD2000338D40E050E0822B932BA42BB52BF601868F978FA0A3B1A3FB01848D958DA68D6E +:20FD4000B78DF601828F938FA48FB58F168A178A108E118E81E0818380E003C086E001C091 +:20FD600083E0EC96E2E11CC181E0FBCF83E0A0CF84E0F7CFA0E0B0E0EFEBFEEFF7C03C010C +:20FD80007B014A01C0910B01D0910C01FA0111821082209709F4A0C0898180FF9FC08A8D9E +:20FDA0009B8DAC8DBD8D2E893F89488D598D821B930BA40BB50B9B0140E050E08217930795 +:20FDC000A407B50708F47C015301412C72E0572E7AC08E899F89A88DB98D9C01AD013170CB +:20FDE000407050702115310541055105C1F59C01AD0169E056954795379527956A95D1F72B +:20FE0000CA80CA94C222C1F40097A105B10529F46E8D7F8D88A199A105C06AA17BA18CA10E +:20FE20009DA186DC623071058105910508F451C06AA37BA38CA39DA36AA17BA18CA19DA1C5 +:20FE400008DC611571058105910509F442C06C0D711D811D911D6EA37FA388A799A72E890B +:20FE60003F893170C201821B930B67018E159F0508F46C016114710419F480E090E001C07B +:20FE8000C5014EA15FA168A579A5860193DB882301F5960140E050E08E899F89A88DB98D4B +:20FEA000820F931FA41FB51F8E8B9F8BA88FB98FAC0CBD1CEC18FD08F401808191818C0D6B +:20FEC0009D1D91838083E114F10409F082CF80E006C0198281E003C086E001C085E0CDB728 +:20FEE000DEB7E0E15FC0629FD001739FF001829FE00DF11D649FE00DF11D929FF00D839F4E +:20FF0000F00D749FF00D659FF00D9927729FB00DE11DF91F639FB00DE11DF91FBD01CF01CC +:20FF200011240895A1E21A2EAA1BBB1BFD010DC0AA1FBB1FEE1FFF1FA217B307E407F50796 +:20FF400020F0A21BB30BE40BF50B661F771F881F991F1A9469F760957095809590959B01CF +:20FF6000AC01BD01CF0108952F923F924F925F926F927F928F929F92AF92BF92CF92DF927D +:20FF8000EF92FF920F931F93CF93DF93CDB7DEB7CA1BDB0B0FB6F894DEBF0FBECDBF09945F +:20FFA0002A88398848885F846E847D848C849B84AA84B984C884DF80EE80FD800C811B81CF +:20FFC000AA81B981CE0FD11D0FB6F894DEBF0FBECDBFED010895DC0101C06D934150504060 +:12FFE000E0F70895F894FFCF66656D752E62696E00002D +:040000050001F00006 +:00000001FF diff --git a/floppy-emu-1.0Q-F13/readme.txt b/floppy-emu-1.0Q-F13/readme.txt new file mode 100755 index 0000000..669b7ba --- /dev/null +++ b/floppy-emu-1.0Q-F13/readme.txt @@ -0,0 +1,24 @@ +To update the Xilinx CPLD firmware: + +1. Copy firmware.xvf to the root directory of your SD card, and insert it into Floppy Emu. +2. Hold down the PREV and NEXT buttons. +3. Press and release the RESET button. +4. Follow the on-screen prompts. + + +To update the microcontroller application software: + +If you have the SD bootloader already installed: +1. Copy femu.bin to the root directory of your SD card, and insert it into Floppy Emu. +2. Hold down the PREV and SELECT buttons. +3. Press and release the RESET button. +4. Follow the on-screen prompts. + +If you don't have the SD bootloader installed: +1. Use your AVR ISP programmer to flash floppyemu.hex to the microcontroller. + +If you want to install the SD bootloader: +1. Use your AVR ISP programmer to flash merged.hex to the microcontroller. +2. Use the ISP programmer to set the BOOTRST fuse to 1 (on), and the BOOTSZ fuse to 2048W_F800. (Fuses should be Extended: 0xFC, High: 0xDA, Low: 0xBF) + + diff --git a/source-1.0L-F11/AVR/Release/Makefile b/source-1.0L-F11/AVR/Release/Makefile new file mode 100755 index 0000000..6c14de7 --- /dev/null +++ b/source-1.0L-F11/AVR/Release/Makefile @@ -0,0 +1,212 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +SHELL := cmd.exe +RM := rm -rf + +USER_OBJS := + +LIBS := +PROJ := + +O_SRCS := +C_SRCS := +S_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +PREPROCESSING_SRCS := +OBJS := +OBJS_AS_ARGS := +C_DEPS := +C_DEPS_AS_ARGS := +EXECUTABLES := +OUTPUT_FILE_PATH := +OUTPUT_FILE_PATH_AS_ARGS := +AVR_APP_PATH :=$$$AVR_APP_PATH$$$ +QUOTE := " +ADDITIONAL_DEPENDENCIES:= +OUTPUT_FILE_DEP:= + +# Every subdirectory with source files must be described here +SUBDIRS := + + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../cardtest.cpp \ +../diskmenu.cpp \ +../floppyemu.cpp \ +../millitimer.cpp \ +../noklcd.cpp \ +../SdFat/Sd2Card.cpp \ +../SdFat/SdBaseFile.cpp \ +../SdFat/SdFat.cpp \ +../SdFat/SdVolume.cpp \ +../xsvf/lenval.cpp \ +../xsvf/micro.cpp \ +../xsvf/ports.cpp + + +PREPROCESSING_SRCS += + + +ASM_SRCS += + + +OBJS += \ +cardtest.o \ +diskmenu.o \ +floppyemu.o \ +millitimer.o \ +noklcd.o \ +Sd2Card.o \ +SdBaseFile.o \ +SdFat.o \ +SdVolume.o \ +lenval.o \ +micro.o \ +ports.o + + +OBJS_AS_ARGS += \ +cardtest.o \ +diskmenu.o \ +floppyemu.o \ +millitimer.o \ +noklcd.o \ +Sd2Card.o \ +SdBaseFile.o \ +SdFat.o \ +SdVolume.o \ +lenval.o \ +micro.o \ +ports.o + + +C_DEPS += \ +cardtest.d \ +diskmenu.d \ +floppyemu.d \ +millitimer.d \ +noklcd.d \ +Sd2Card.d \ +SdBaseFile.d \ +SdFat.d \ +SdVolume.d \ +lenval.d \ +micro.d \ +ports.d + + +C_DEPS_AS_ARGS += \ +cardtest.d \ +diskmenu.d \ +floppyemu.d \ +millitimer.d \ +noklcd.d \ +Sd2Card.d \ +SdBaseFile.d \ +SdFat.d \ +SdVolume.d \ +lenval.d \ +micro.d \ +ports.d + + +OUTPUT_FILE_PATH +=floppyemu.elf + +OUTPUT_FILE_PATH_AS_ARGS +=floppyemu.elf + +ADDITIONAL_DEPENDENCIES:= + +OUTPUT_FILE_DEP:= ./makedep.mk + +# AVR32/GNU C Compiler + + + + + + + + + + + + + + + + + + + + + + + +./%.o: .././%.cpp + @echo Building file: $< + @echo Invoking: AVR8/GNU C++ Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -I"../SdFat" -I"../xsvf" -O2 -ffunction-sections -fpack-struct -fshort-enums -Wall -c -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<" + @echo Finished building: $< + +./%.o: ../SdFat/%.cpp + @echo Building file: $< + @echo Invoking: AVR8/GNU C++ Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -I"../SdFat" -I"../xsvf" -O2 -ffunction-sections -fpack-struct -fshort-enums -Wall -c -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<" + @echo Finished building: $< + +./%.o: ../xsvf/%.cpp + @echo Building file: $< + @echo Invoking: AVR8/GNU C++ Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -I"../SdFat" -I"../xsvf" -O2 -ffunction-sections -fpack-struct -fshort-enums -Wall -c -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<" + @echo Finished building: $< + + + +# AVR32/GNU Preprocessing Assembler + + + +# AVR32/GNU Assembler + + + + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES) + +$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) + @echo Building target: $@ + @echo Invoking: AVR8/GNU C++ Linker + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="floppyemu.map" -Wl,-lm -Wl,--gc-sections -mrelax -Wl,-section-start=.bootldrinfo=0x1eff8 -mmcu=atmega1284p + @echo Finished building target: $@ + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "floppyemu.elf" "floppyemu.hex" + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -O binary -R .eeprom -R .fuse -R .lock -R .signature "floppyemu.elf" "femu.bin" + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "floppyemu.elf" "floppyemu.eep" || exit 0 + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objdump.exe" -h -S "floppyemu.elf" > "floppyemu.lss" + srec_cat "floppyemu.hex" -intel "..\bootldr\bootldr\Release\bootldr.hex" -intel -o "merged.hex" -intel + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-size.exe" -C --mcu=atmega1284p "floppyemu.elf" + + + + + + + +# Other Targets +clean: + -$(RM) $(OBJS_AS_ARGS)$(C_DEPS_AS_ARGS) $(EXECUTABLES) + rm -rf "floppyemu.hex" "floppyemu.lss" "floppyemu.eep" "floppyemu.map" + \ No newline at end of file diff --git a/source-1.0L-F11/AVR/Release/femu.bin b/source-1.0L-F11/AVR/Release/femu.bin new file mode 100755 index 0000000..7980912 Binary files /dev/null and b/source-1.0L-F11/AVR/Release/femu.bin differ diff --git a/source-1.0L-F11/AVR/Release/floppyemu.hex b/source-1.0L-F11/AVR/Release/floppyemu.hex new file mode 100755 index 0000000..3bbc610 --- /dev/null +++ b/source-1.0L-F11/AVR/Release/floppyemu.hex @@ -0,0 +1,1983 @@ +:10000000B2C30000DFC30000DDC30000DBC300009B +:100010000C941F0ED7C300000C94AB0A0C94F70984 +:10002000D1C30000CFC30000CDC30000CBC300008C +:10003000C9C30000C7C30000C5C30000C3C300009C +:10004000C1C30000BFC300000C945A1DBBC3000015 +:10005000B9C30000B7C30000B5C30000B3C30000BC +:10006000B1C30000AFC30000ADC30000ABC30000CC +:10007000A9C30000A7C30000A5C30000A3C30000DC +:10008000A1C300009FC300009DC3000000000C003E +:100090001800240030003C004800540060006C0050 +:1000A0007800840090009C00A800B400C000CB0041 +:1000B000D600E100EC00F70002010D011801230158 +:1000C0002E01390144014F015A01650170017A0185 +:1000D00084018E019801A201AC01B601C001CA01E0 +:1000E000D401DE01E801F201FC010602100219024E +:1000F00022022B0234023D0246024F0258026102E4 +:100100006A0273027C0285028E029702A002A80294 +:10011000B002B802C002C802D002D802E002E8026F +:10012000F002F80200030803100318030C0C0C0C77 +:100130000C0C0C0C0C0C0C0C0C0C0C0C0B0B0B0B03 +:100140000B0B0B0B0B0B0B0B0B0B0B0B0A0A0A0A03 +:100150000A0A0A0A0A0A0A0A0A0A0A0A0909090903 +:100160000909090909090909090909090808080803 +:1001700008080808080808080808080896979A9BBD +:100180009D9E9FA6A7ABACADAEAFB2B3B4B5B6B7AC +:10019000B9BABBBCBDBEBFCBCDCECFD3D6D7D9DAD3 +:1001A000DBDCDDDEDFE5E6E7E9EAEBECEDEEEFF2E6 +:1001B000F3F4F5F6F7F9FAFBFCFDFEFF0001FFFF93 +:1001C0000203FF040506FFFFFFFFFFFF0708FFFF15 +:1001D000FF090A0B0C0DFFFF0E0F10111213FF1475 +:1001E00015161718191AFFFFFFFFFFFFFFFFFFFF8C +:1001F000FF1BFF1C1D1EFFFFFF1FFFFF2021FF2213 +:10020000232425262728FFFFFFFFFF292A2BFF2C69 +:100210002D2E2F303132FFFF333435363738FF394A +:100220003A3B3C3D3E3F0000211042206330844079 +:10023000A550C660E770088129914AA16BB18CC1B5 +:10024000ADD1CEE1EFF13112100273325222B5522C +:100250009442F772D662399318837BB35AA3BDD305 +:100260009CC3FFF3DEE36224433420040114E664FC +:10027000C774A44485546AA54BB528850995EEE555 +:10028000CFF5ACC58DD55336722611163006D7760C +:10029000F6669556B4465BB77AA719973887DFF7A5 +:1002A000FEE79DD7BCC7C448E5588668A7784008D4 +:1002B000611802282338CCC9EDD98EE9AFF94889F5 +:1002C00069990AA92BB9F55AD44AB77A966A711A6C +:1002D000500A333A122AFDDBDCCBBFFB9EEB799B45 +:1002E000588B3BBB1AABA66C877CE44CC55C222CBC +:1002F000033C600C411CAEED8FFDECCDCDDD2AAD95 +:100300000BBD688D499D977EB66ED55EF44E133E4B +:10031000322E511E700E9FFFBEEFDDDFFCCF1BBFE4 +:100320003AAF599F788F8891A981CAB1EBA10CD1BE +:100330002DC14EF16FE18010A100C230E3200450C6 +:10034000254046706760B9839893FBA3DAB33DC339 +:100350001CD37FE35EF3B1029012F322D232354216 +:10036000145277625672EAB5CBA5A89589856EF5C9 +:100370004FE52CD50DC5E234C324A0148104667466 +:10038000476424540544DBA7FAB79987B8975FE719 +:100390007EF71DC73CD7D326F2369106B0165766B6 +:1003A0007676154634564CD96DC90EF92FE9C899A1 +:1003B000E9898AB9ABA94458654806782768C01806 +:1003C000E1088238A3287DCB5CDB3FEB1EFBF98B79 +:1003D000D89BBBAB9ABB754A545A376A167AF10A56 +:1003E000D01AB32A923A2EFD0FED6CDD4DCDAABD89 +:1003F0008BADE89DC98D267C076C645C454CA23CA6 +:10040000832CE01CC10C1FEF3EFF5DCF7CDF9BAF58 +:10041000BABFD98FF89F176E367E554E745E932EF5 +:10042000B23ED10EF01E20202020202020202020AF +:100430002020202020202020202020002049646C23 +:1004400065002052656164005772697465005472DA +:1004500061636B202020205369646500313434309F +:100460004B204469736B436F707920696D616765D8 +:10047000003830304B204469736B436F70792069CA +:100480006D616765003430304B204469736B436F96 +:10049000707920696D61676500313434304B2072AA +:1004A000617720696D616765003830304B2072617B +:1004B0007720696D616765003430304B2072617759 +:1004C00020696D61676500696D616765206E6F7495 +:1004D00020636F6E746967756F7573006572726FF4 +:1004E00072206F70656E696E6720696D6167650067 +:1004F000505245563A2043616E63656C004E455834 +:10050000543A204C6F6164206669726D7761726540 +:1005100000626567696E0052656C65617365206293 +:100520007574746F6E7320746F0043504C44204692 +:1005300049524D574152452055504441544500437E +:100540006F6E74726173743A200053454C45435486 +:100550003A2053617665004E4558543A2044617202 +:100560006B657200505245563A204C696768746555 +:100570007200626567696E0052656C656173652023 +:10058000627574746F6E7320746F00434F4E5452D3 +:100590004153542041444A5553544D454E54004113 +:1005A00070702056657273696F6E20312E30204C4A +:1005B000002020202020464C4F50505920454D55BA +:1005C00020202020202000507265737320616E79F6 +:1005D00020627574746F6E006669726D7761726502 +:1005E0002E78766600436F756C64206E6F74206F92 +:1005F00070656E005570646174696E67206669721B +:100600006D776172652E2E2E00464154414C204577 +:1006100052524F52202020202020202020200057FE +:1006200052495445204552524F522020202020202C +:1006300020202020000000000017000300031F0AF4 +:100640001F0A1F050904120F171C000303000E11D7 +:10065000110E00050205040E041008000404040035 +:1006600010001804031E110F021F00191512151592 +:100670000A07041F1715091E151D1905031A150B66 +:1006800017150F000A00040C04040E1F0A0A0A1FA3 +:100690000E040115030E15161E051E1F150A0E1158 +:1006A000111F110E1F15151F05050E151D1F041F07 +:1006B000111F1108100F1F041B1F10101F061F1FF2 +:1006C0000E1F0E110E1F05020E191E1F0D161215FC +:1006D00009011F010F101F0718071F0C1F1B041B08 +:1006E000031C031915131F101002040810101F0417 +:1006F00006041010100003031A161C1F120C0C1213 +:10070000120C121F0C1A16041E050C2A1E1F021CA6 +:10071000001D0010201D1F0C12111F101E0E1E1E8A +:10072000021C0C120C3E120C0C123E1C0202141E77 +:100730000A021F120E101E0E180E1E1C1E120C1284 +:1007400006281E1A1F16041B11001F00111B040887 +:100750000C047C3C3E5E2B3D3F2F5B5D3B2C2A22F4 +:100760005C00451D491D11241FBECFEFD0E4DEBF44 +:10077000CDBF13E0A0E0B1E0EAE9F9E700E00BBF8C +:1007800002C007900D92A831B107D9F717E3A8E18D +:10079000B3E001C01D92AD3DB107E1F717E000E005 +:1007A000C4E6D7E040E006C022974109FE014BBFF6 +:1007B0000E947A39C236D1074007B1F70E94191852 +:1007C0000C94BC3C1DCC2F923F924F925F926F9243 +:1007D0007F928F929F92AF92BF92CF92DF92EF92D1 +:1007E000FF920F931F93DF93CF93CDB7DEB72D9773 +:1007F0000FB6F894DEBF0FBECDBF8B014A013E019C +:100800000894611C711CD301E4E2F1E02DE0019039 +:100810000D922150E1F7BB244424AA2452E8552E1E +:1008200042E2E42EF12CE80EF91E3EE0C32ED12C5C +:10083000CC0EDD1E22E8222E312C280C391CC701DB +:10084000B80140E250E00E94C92480329105A1F431 +:10085000D8011B968C911B9790E09C012F733070F0 +:100860002F30310559F183FD23C0F8018081853E89 +:1008700019F1882309F05AC0D4011C9280E02D960A +:100880000FB6F894DEBF0FBECDBFCF91DF911F91A1 +:100890000F91FF90EF90DF90CF90BF90AF909F901F +:1008A0008F907F906F905F904F903F902F90089522 +:1008B000F8018081882301F3BB24C1CFBB2021F53F +:1008C0008C91982F907E903409F0B9CF9FE1A92E9A +:1008D000A8221D964C90F1011082A5E7B0E085E7B3 +:1008E000582EF301AD01480D591D81919801280F33 +:1008F000311DD9018C91DA018D93AD01EC15FD0507 +:10090000A1F7BB24B3949BCFD8018C91AA948A15EC +:1009100099F61D968C911D97841571F6552009F452 +:100920008ECFB3EF5B0EA52DB0E0DBCF8E3221F280 +:10093000BB2081F031962BE090E001C08191392FEE +:100940003795332737959695932B980F2150B1F70C +:10095000941531F0C801B4010E94092481E08FCFC1 +:10096000FA2DF130B9F7452D50E043385105B4F771 +:100970009A0160E080E090E0880D991D280D391DF6 +:10098000D9012C91FC0120836F5F862F90E09C01A0 +:10099000240F351F233831057CF381E070CFEF92AF +:1009A000FF920F931F93DF93CF93CDB7DEB7A99735 +:1009B0000FB6F894DEBF0FBECDBFFC01DB018C91FA +:1009C0008E32A9F1838590E0887190708031910515 +:1009D00009F466C0009759F5848D958DA68DB78D65 +:1009E000803020E4920726E0A20720E0B20709F455 +:1009F00059C0803020E892072CE0A20720E0B2071F +:100A000009F454C0803020E8920726E1A20720E0D4 +:100A1000B20709F449C081509044A640B0408F3FCE +:100A20002FE2920721E1A20720E0B20778F020E050 +:100A3000822FA9960FB6F894DEBF0FBECDBFCF911F +:100A4000DF911F910F91FF90EF900895CF017E01EC +:100A50000894E11CF11CB7010E9409241E86198A22 +:100A60008E01025F1F4FC801B70141E00E94342A86 +:100A7000882371F0C80165E773E340E052E00E940B +:100A8000C924C8010E9433278091C733813081F087 +:100A90008989882361F2C8010E94332720E0C8CFEA +:100AA00021E0C6CF23E0C4CF25E0C2CF24E0C0CFF1 +:100AB0008091C833882361F78091B63390E0A0E03D +:100AC000B0E0BA2FA92F982F88272091B733820F33 +:100AD000911DA11DB11DB695A79597958795B695C2 +:100AE000A79597958795803921E0920720E0A20786 +:100AF00020E0B207F1F0803223E0920720E0A20765 +:100B000020E0B207A1F0803A25E0920720E0A2079A +:100B100020E0B20709F0BCCF28E08989882309F4D6 +:100B200087CFC80129A70E94332729A581CF27E0B5 +:100B3000F4CF26E0F2CF2F923F924F925F926F92C6 +:100B40007F928F929F92AF92BF92CF92DF92EF925D +:100B5000FF920F931F93DF93CF93CDB7DEB7C05FA4 +:100B6000D0400FB6F894DEBF0FBECDBF7C0110920F +:100B7000190310921803829640E050E0BA010E94D7 +:100B80004B2603E4C02ED12CCC0EDD1E13E6A12E85 +:100B9000B12CAC0EBD1EB4E26B2E712CC701B60198 +:100BA000A50111DE8823E1F18091180390911903CA +:100BB00021E08734920708F0A7C1C601B501EFDE36 +:100BC000882E882359F38091180390911903869DEC +:100BD0008001879D100D969D100D11240B581C4F00 +:100BE000C801B50146E150E00E94B339B8016A5E20 +:100BF0007F4FC6010E940924809118039091190328 +:100C0000869DF001879DF00D969DF00D1124EB5807 +:100C1000FC4F83A201969093190380931803BECFD3 +:100C20002091180330911903C751DF4F398328836E +:100C3000C95ED040F70185A182508230A8F184E2DC +:100C400090E0C751DF4FE881F981C95ED040E89F4D +:100C50008001E99F100DF89F100D11240B581C4FB7 +:100C6000C80160E071E046E150E00E94B339C8017C +:100C7000469660E071E04DE050E00E94B33982E0BA +:100C8000F80183A3C751DF4F28813981C95ED04065 +:100C90002F5F3F4FC751DF4F39832883C95ED04054 +:100CA0003093190320931803A8E92A2EA3E03A2EC3 +:100CB00080E090E07E010894E11CF11CF7E1CF2E6A +:100CC000D12CCC0EDD1EC751DF4FE881F981C95E02 +:100CD000D0408E179F0708F01EC1FC013196C3510A +:100CE000DF4FF983E883CD5ED040C751DF4F2881C5 +:100CF0003981C95ED040E217F30708F026C1C1016F +:100D00008397F101B496C151DF4FF983E883CF5E39 +:100D1000D0405F01C351DF4F48805980CD5ED04045 +:100D2000CA51DF4F8883C65ED04091012D503040BC +:100D3000C551DF4F39832883CB5ED040C951DF4F87 +:100D400039822882C75ED040392EC701CA51DF4F91 +:100D50006881C65ED040732D46E150E00E94B339F1 +:100D600088240AC00E0D1F1DF801808190E00E94AA +:100D70007E39F80180838394F70101900020E9F720 +:100D80003197EE19FF09082D10E00E171F0750F3D9 +:100D9000EDED8E2EEFEF9E2E8A0C9B1C682C292CDD +:100DA000C601B40146E150E00E94B33977240AC07D +:100DB0000C0D1D1DF801808190E00E947E39F80124 +:100DC00080837394F60101900020E9F73197EC19C4 +:100DD000FD09072D10E00E171F0750F3C701B601DC +:100DE00046E150E00E94A539282F392FC951DF4F25 +:100DF000E881F981C75ED04080818150823008F45B +:100E000080C0F50180818150823008F477C01216CD +:100E100013060CF055C0CE018D96CA51DF4F688184 +:100E2000C65ED040732D46E150E00E94B339CA51EE +:100E3000DF4F8881C65ED040932D662D722D46E12E +:100E400050E00E94B339862D922DBE01635D7F4F25 +:100E500046E150E00E94B339CE018D96C551DF4F77 +:100E600068817981CB5ED0404DE050E00E94B3397B +:100E700084010A5E1F4FC551DF4F88819981CB5E87 +:100E8000D040B8014DE050E00E94B339C801BE0126 +:100E9000635D7F4F4DE050E00E94B339C951DF4F91 +:100EA000E881F981C75ED0408081F5019081C95108 +:100EB000DF4FE881F981C75ED0409083F5018083E0 +:100EC0000894411C511C24E230E0A20EB31EC7510D +:100ED000DF4F88819981C95ED0404816590608F4D1 +:100EE00034CFC151DF4F28803980CF5ED040C3510D +:100EF000DF4F88819981CD5ED040E5CE28513C4FAF +:100F000086CF285E33407DCFC751DF4F99838883DA +:100F1000C95ED0408FCEC051DF4F0FB6F894DEBF10 +:100F20000FBECDBFCF91DF911F910F91FF90EF903A +:100F3000DF90CF90BF90AF909F908F907F906F90F9 +:100F40005F904F903F902F900895C1018496C151BA +:100F5000DF4F99838883CF5ED040C3CF8F929F921B +:100F6000AF92BF92CF92DF92EF92FF920F931F93B7 +:100F7000CF93DF9380911A0390911B0320911C0360 +:100F800030911D032817390728F430931B03209351 +:100F90001A03C90104968217930730F42450304095 +:100FA00030931B0320931A0380E060E00E949A1D97 +:100FB00081E06FE70E948B1DC3E1D0E081E060E437 +:100FC0000E948B1D2197D1F783E091E00E948F1E34 +:100FD000C3E1D0E081E060E40E948B1D2197D1F74E +:100FE00081E06FE70E948B1D209118033091190357 +:100FF0002115310509F464C140911A0350911B0376 +:10100000CA0105964817590708F033C1421753071C +:1010100008F02FC164E270E0469F7001479FF00C1A +:10102000569FF00C112488E993E0E80EF91EEA01BE +:1010300091E0C92ED12CBB24B39480911C039091D4 +:101040001D03C817D90709F0BB24AC2C80E06C2D18 +:101050000E949A1D04E510E007C060E081E00E9454 +:101060008B1D0150104049F0BB20B9F36FE781E0C0 +:101070000E948B1D01501040B9F781E06A2D0E943B +:101080009A1D870103521040902E812EC8016B2DAE +:1010900043E50E94A61DF70180818150823008F44B +:1010A000BDC0BB2009F0A4C08601219640911A035F +:1010B00050911B03CA010596C817D907E0F120918A +:1010C0001803309119032630310508F047C0EE248B +:1010D000E39482E56E2D0E949A1D81E060E00E94FB +:1010E0008B1D81E060E00E948B1DE3947E2D7630A5 +:1010F00081F780911A0390911B039801280F391FE3 +:1011000040911C0350911D034217530708F4E2C09D +:101110002150304030931D0320931C0304301105EF +:1011200009F02CCF009709F429CF019790931B0366 +:1011300080931A0323CF2091180330911903089448 +:10114000C11CD11C64E270E0E60EF71EC217D30783 +:1011500008F471CF2630310508F4B9CFE7E2F0E0AA +:101160004E9FC0014F9F900D5E9F900D11248D5397 +:101170009F4FB9010E94293988E0E82EE60E83ECE2 +:1011800090E0B9010E942939CE2CC61AC8E0D0E0FF +:10119000BB24B39482E56B2D0E949A1D81E060E030 +:1011A0000E948B1D4C2F9E01295F3F4F2C173D073E +:1011B0000CF484C060E00AC0E41650F066956068E4 +:1011C0004F5F842F90E0281739074CF04C15A0F79B +:1011D00066954F5F842F90E028173907BCF781E0B0 +:1011E0000E948B1DB39428967B2D763099F681CF83 +:1011F00084E393E0692D782D46E150E00E94B339F5 +:10120000B8016A5E7F4F8EE193E04DE050E00E94AE +:10121000B339F701808180934A0346CF89E46A2D70 +:101220000E949A1DBB2041F181E06FE70E948B1D57 +:1012300081E063E40E948B1D81E06DE50E948B1DBF +:1012400081E06DE50E948B1D81E06DE50E948B1DA4 +:1012500081E06BE50E948B1D81E06BE50E948B1D98 +:1012600081E063E40E948B1D6FE781E00E948B1D8B +:1012700018CF00E010E027CF81E060E00E948B1DD6 +:1012800081E06CE30E948B1D81E062E20E948B1D75 +:1012900081E062E20E948B1D81E062E20E948B1D70 +:1012A00081E064E20E948B1D81E064E20E948B1D5C +:1012B00081E06CE30E948B1D60E0D7CF60E08FCFB0 +:1012C00080E061E00E949A1D8FE091E060E044E5DB +:1012D0000E94A61DDF91CF911F910F91FF90EF907B +:1012E000DF90CF90BF90AF909F908F900895813006 +:1012F000910559F0009721F48091A135882309F4D4 +:1013000008958EE995E30C94332710929E35109240 +:10131000A13508958FE781B9559A209A3A9A3D9A56 +:101320003E9A3B9A239A5C9A599A5A9A5F9A5B9A88 +:10133000179A589A409A419A289A429A45984698FC +:10134000439A2B9AE3E7F0E0808181608083EDE6A9 +:10135000F0E0808182608083808181608083089555 +:101360001F93DF93CF93CDB7DEB72A970FB6F894CC +:10137000DEBF0FBECDBFCE010196DC01EEEDF2E087 +:101380002AE001900D922150E1F7E0914C03F0E04A +:10139000F595E795F595E795F595E795F595E79535 +:1013A0001FB7F894E53008F0E4E0F0E0EE0FFF1F1F +:1013B000E80FF91F20813181220F331F40E050E0F8 +:1013C00060E07DE281E391E00E945F3930935B034E +:1013D00020935A031FBF82E086BB2A960FB6F8946B +:1013E000DEBF0FBECDBFCF91DF911F9108951F9239 +:1013F0000F920FB60F920BB60F9211242F933F93BB +:101400004F935F936F937F938F939F93AF93BF930C +:10141000CF93DF93EF93FF93489B2FC0E0914C0352 +:1014200080915503882309F03DC0F0E0E45DFE4F54 +:10143000249130E0220F331F21153105A9F537998A +:101440005DC080914C038F5F80934C0380914C036F +:10145000882309F064C04598429A4899FECF429883 +:10146000459A7EDFC0919435D0919535C330D10532 +:1014700008F057C081E080935103FF91EF91DF9115 +:10148000CF91BF91AF919F918F917F916F915F911C +:101490004F913F912F910F900BBE0F900FBE0F9069 +:1014A0001F90189524E230E080E090E040E050E0AA +:1014B00068E188589A4CFC01808180FF03C0683144 +:1014C00059F1542F4F5F842F90E0821793070CF14E +:1014D000561708F4B4CF862FE82FF0E0E858FA4CFE +:1014E000908191FF03C0908191609083908194607E +:1014F00090838F5F581780F7379BA3CF80914C0361 +:10150000882309F4A3CF80914C03815080934C032E +:101510009DCF4831E9F2CDCF542F642FD3CF459AD8 +:101520009BCF8FE593E061E371E046E150E00E94DC +:10153000B339C851DC4FD0937735C09376351092CC +:10154000500381E0809351038093520310929535AC +:10155000109294358FCF1F920F920FB60F920BB649 +:101560000F9211241F932F933F934F935F936F9389 +:101570007F938F939F93AF93BF93CF93DF93EF931B +:10158000FF9386B190E095958795817090914E0379 +:10159000891791F090915803923009F46DC0109220 +:1015A0004E0311E010935103C0919435D0919535BD +:1015B000C330D10508F047C086B1817011E08127A2 +:1015C000909150038917C9F0809350038091500384 +:1015D000882349F58FE781B9469880916B008F7712 +:1015E00080936B00C0919435D0919535C330D1056F +:1015F00008F045C081E080935103FF91EF91DF91A6 +:10160000CF91BF91AF919F918F917F916F915F919A +:101610004F913F912F911F910F900BBE0F900FBED6 +:101620000F901F90189511B8469A80916B008068B2 +:1016300080936B0080B180788093933510929535BC +:1016400010929435D7CF8FE593E061E371E046E1E6 +:1016500050E00E94B339C053D84FD0937735C09330 +:101660007635109250031093510310935203109249 +:10167000953510929435A0CF80934E0392CF8FE58D +:1016800093E061E371E046E150E00E94B339C85451 +:10169000D44FD0937735C093763510925003109382 +:1016A0005103109352031092953510929435A2CFA6 +:1016B0001F93E0B1E0688091943590919535843026 +:1016C000910588F48330910509F487C0DC01A153AA +:1016D000BD4F2C912E1709F404C11092953510922C +:1016E00094351F910895F0E0EA5DFE4FE49132E0F9 +:1016F0008F3B930748F59C012370307022303105F1 +:1017000009F4BBC02330310509F449C1213031054A +:1017100009F418C1EE0FEE0FE093963540919A351B +:1017200050E09A01220F232F221F330B20939B3569 +:10173000440F551F422B40939A350196909395354F +:10174000809394351F910895F2E08F3B9F0709F431 +:10175000C1C022E0803C920709F4CEC032E0813C57 +:10176000930709F4E2C1F2E0823C9F0709F0B5CF8C +:1017700080919635982F990F990F90939635E82B75 +:1017800090919A35E917C9F08FE593E062E971E02D +:1017900046E150E00E94B33980E490E090937735C1 +:1017A000809376351092500381E0809351038093AB +:1017B00052031092953510929435E0919735F0E0F0 +:1017C000E858FA4C808182608083808181608083C8 +:1017D00080818B7F80832B9A80CFF0E0EA5DFE4F83 +:1017E0001491E0914C0380915503882309F082C045 +:1017F000F0E0E45DFE4FE4911E1708F04DC1E0916A +:101800004C03882309F074C0F0E0E45DFE4FE491DE +:1018100080914E03E89F802D1124810F809397358E +:1018200090E0DC01A858BA4C2C9122FDE0C0982F22 +:101830008827990F8B589C4F90939D3580939C35AA +:101840008C9184608C938C918D7F8C9380914C03D0 +:101850008093903580914E0380939135109392350B +:101860002B9810929A351092993510929835809154 +:10187000943590919535019661CF50919635452FCD +:10188000407C4E2B2091983542278431910578F089 +:10189000E0919C35F0919D354193F0939D35E09317 +:1018A0009C35509196358091943590919535609105 +:1018B0009B352091993530E0260F311D240F311DC5 +:1018C0002093993530939B35550F550F509396358E +:1018D000019634CFEE0FEE0FE093963580EC92E058 +:1018E0002DCF20915403222309F0F7CE019626CF65 +:1018F000E2E18ECFE2E180CF80919635982F990F6B +:10190000990F90939635807C8E2B909198358917FE +:1019100009F46AC08FE593E06CE671E046E150E0BF +:101920000E94B3398EE390E09093773580937635BB +:101930001092500381E0809351038093520381E021 +:1019400090E0FCCE50919635452F407C4E2B209157 +:101950009A3542278431910578F0E0919C35F091D9 +:101960009D354193F0939D35E0939C35509196358C +:10197000809194359091953560919B352091983563 +:1019800030E0260F311D240F311D20939835309300 +:101990009B35550F550F509396350196CFCE4091FC +:1019A00096354E2B2091993542278431910568F068 +:1019B000E0919C35F0919D354193F0939D35E093F6 +:1019C0009C35809194359091953550919B3520911F +:1019D0009A3530E0250F311D240F311D20939A35A3 +:1019E00030939B350196AACE81EC92E0A7CE309140 +:1019F0004C0320914E038DB79EB70C970FB6F89409 +:101A00009EBF0FBE8DBFADB7BEB711968FE593E0F9 +:101A1000EDB7FEB79283818386E190E013969C93A5 +:101A20008E93129788E591E015969C938E93149768 +:101A300016963C93169717961C92179718962C9308 +:101A4000189719961C9219971A961C931A971B9619 +:101A50001C920E94C2398DE390E090937735809379 +:101A600076351092500381E08093510380935203A6 +:101A700010929535109294358091973590E02DB75E +:101A80003EB7245F3F4F0FB6F8943EBF0FBE2DBF49 +:101A9000DC01A858BA4CCBCE20914C038DB79EB731 +:101AA0000A970FB6F8949EBF0FBE8DBFADB7BEB7F5 +:101AB00011968FE593E0EDB7FEB79283818386E1BF +:101AC00090E013969C938E93129782E491E0159682 +:101AD0009C938E93149716961C93169717961C92A8 +:101AE000179718962C93189719961C920E94C23932 +:101AF0008CE390E090937735809376351092500385 +:101B000081E0809351038093520310929535109297 +:101B10009435809155032DB73EB7265F3F4F0FB6E2 +:101B2000F8943EBF0FBE2DBF6ACE80919635982F98 +:101B3000990F990F90939635807C8E2B90919935C3 +:101B4000891759F08FE593E06FE771E046E150E0C7 +:101B50000E94B3398FE390E0E7CE82EC92E0EECDC5 +:101B60004091560350915703E2EEF2E025913491F3 +:101B700060E07FEF2627372791EA692F632770E01F +:101B8000660F771F6A5D7D4FFB0165917491322F5F +:101B90002227262737279327E92FF0E0EE0FFF1F94 +:101BA000EA5DFD4F65917491322F22272627372752 +:101BB000EBEFE327F0E0EE0FFF1FEA5DFD4F6591CD +:101BC0007491322F222726273727B82FBB0FA0E08A +:101BD000AB58BC4F80E090E0722F6627ED91E32771 +:101BE000F0E0EE0FFF1FEA5DFD4F259134912627AF +:101BF0003727019662E08030960771F730935703DC +:101C00002093560342175307C9F08FE593E065EA26 +:101C100071E046E150E00E94B33986E490E0909391 +:101C20007735809376351092500381E0809351038D +:101C300080935203109295351092943508951F9217 +:101C40000F920FB60F920BB60F9211242F933F9362 +:101C50004F935F936F937F938F939F93AF93BF93B4 +:101C6000EF93FF9390B180915003882309F456C0FD +:101C7000892F807890919335891709F44FC080930C +:101C8000933590915503992309F46FC0882309F483 +:101C900061C020B12F7080919635282B2093963506 +:101CA00080919435909195358230910509F45FC00B +:101CB000009709F446C08130910509F46DC032E007 +:101CC0008330930708F458C0A2E083309A0709F4E0 +:101CD0009AC0B2E084309B0709F530E0809156034A +:101CE00090915703822B932B909357038093560325 +:101CF0008091973535DFE0919735F0E0E858FA4C60 +:101D000080818260808380818160808380818B7FFD +:101D100080832B9A1092953510929435FF91EF9114 +:101D2000BF91AF919F918F917F916F915F914F91F3 +:101D30003F912F910F900BBE0F900FBE0F901F90F1 +:101D40001895213A59F781E090E09093953580936A +:101D50009435E4CF80B190E082959295907F98275A +:101D6000807F982780939635D9CFA2DCD7CF2B3FA1 +:101D7000E9F0213A79F6D2CF30919735F32FFF0F62 +:101D8000E0E0E80FF91FEE58FC4F20830196909396 +:101D9000953580939435C2CF213A09F0BBCF82E0CC +:101DA00090E09093953580939435B8CF83E090E0A0 +:101DB00090939535809394352091590320939735CE +:101DC000822F90E0FC01E858FA4C308132FD26C0A9 +:101DD000982F8827990F8B589C4F90939D3580930F +:101DE0009C3580818460808380818D7F8083809119 +:101DF0004C038093903580914E03809391352093CE +:101E000092352B988BCF109256032093570384E082 +:101E100092E0909395358093943580CF50914C0308 +:101E200040914E032DB73EB72C5030400FB6F8947A +:101E30003EBF0FBE2DBFEDB7FEB731962FE533E0A5 +:101E4000ADB7BEB712963C932E93119726E130E0C2 +:101E50003383228328E531E0358324835683178238 +:101E600040871186938782870E94C23987E490E079 +:101E700090937735809376351092500381E080936C +:101E800051038093520310929535109294352DB7DB +:101E90003EB7245F3F4F0FB6F8943EBF0FBE2DBF35 +:101EA0003DCFF89490915003992341F48F7782B9F4 +:101EB000459A079BFECF0799FECF459878940895E1 +:101EC0008AE082B9459A079BFECF0799FECF4598D5 +:101ED000E091570381EAE827F0E0EE0FFF1FEA5D8B +:101EE000FD4F859194913091560320E082279327EE +:101EF000909357038093560381E182B9459A079BDB +:101F0000FECF0799FECF45980895982F92959F7020 +:101F100092B9459A079BFECF0799FECF4598482F67 +:101F20004F70E0915703E827F0E0EE0FFF1FEA5DE6 +:101F3000FD4F859194913091560320E0822793279D +:101F4000909357038093560342B9459A079BFECF5F +:101F50000799FECF459808952F923F924F925F9236 +:101F60006F927F928F929F92AF92BF92CF92DF92A9 +:101F7000EF92FF920F931F93DF93CF9300D00F92B6 +:101F8000CDB7DEB78983692EA2EDCA2EA2E0DA2E84 +:101F9000992422243324EE24FF2400E010E088C09A +:101FA0001070C801880F991F2801440C452C441C4F +:101FB00055085194482A592AF6010191852D9927EF +:101FC000820D931D800F911DAFEF4A225524D6013B +:101FD0001196AC906F010894C11CD11CA7014A0D49 +:101FE000511D9C0120703170232F3327420F531F46 +:101FF0003FEF232E312C2822392271802FEFE22E41 +:10200000F12CE422F522872C8E24042510E0A22452 +:10201000BB24F501E07CF070F595E795F595E79523 +:10202000F595E795F595E7959801207C3070359505 +:10203000279535952795E22BF32B882D829586954C +:102040008695837090E0E82BF92BE458FE4F84913D +:102050004A835B8326DF0F73107004581E4FF8010C +:1020600084911FDF809151034A815B81882309F0AD +:10207000A9C00894C11CD11C8201070D111D40701C +:102080005170452F5527040F151FF501EF73F070A0 +:10209000E458FE4F849105DFE82DF0E0EF73F07017 +:1020A000E458FE4F8491FDDE9394F92DFE3A41F001 +:1020B000292D243009F074CF9981C92ED62C70CFE8 +:1020C0001070C801880F991F5801AA0CAB2CAA1CCC +:1020D000BB08B194A82AB92AD6010C91200E311C54 +:1020E0008B2D9927280E391E1196CC90EC0CF11CE3 +:1020F000C10180709170892F9927E80EF91E0A2579 +:1021000010E0C224DD24F601E07CF070F595E7953F +:10211000F595E795F595E795F595E795C801807CE8 +:1021200090709595879595958795E82BF92BE458B0 +:10213000FE4F8491B6DEF801EF73F070E458FE4F65 +:102140008491AFDEF601EF73F070E458FE4F849196 +:10215000A8DEF101E07CF070F695E795F695E7953D +:10216000C501807C90700024880F991F001C880F87 +:10217000991F001C892F902DE82BF92BC701807C1B +:102180009070929582958F7089279F708927E82B90 +:10219000F92BE458FE4F849184DEF101EF73F07067 +:1021A000E458FE4F84917DDEF701EF73F070E45840 +:1021B000FE4F849176DEF501EF73F070E458FE4F28 +:1021C00084916FDE0F900F900F90CF91DF911F9150 +:1021D0000F91FF90EF90DF90CF90BF90AF909F90C6 +:1021E0008F907F906F905F904F903F902F900895C9 +:1021F000CF93DF9380E060E00E949A1D81EB95E031 +:1022000061E00E94271E8FE995E00E948639819542 +:10221000880F865D62E00E949A1D8FE995E060E07C +:102220000E94271E4DB75EB7485050400FB6F89435 +:102230005EBF0FBE4DBFEDB7FEB73196CFE5D3E021 +:10224000ADB7BEB71296DC93CE93119786E190E0BE +:102250009383828383EB91E09583848380915E03F3 +:10226000868317820E94C239FE0101900020E9F79F +:102270003197EC1BFD0B4DB75EB7485F5F4F0FB654 +:10228000F8945EBF0FBE4DBF8E2F8195880F865D7F +:1022900063E00E949A1DCE0160E044E50E94A61D05 +:1022A0002B980E94531D95E028E04FEF53ED60E31B +:1022B000415050406040E1F700C0000085B18227E6 +:1022C00085B9915091F70E94571DDF91CF910895E4 +:1022D000CF92DF92EF92FF920F931F93DF93CF93F2 +:1022E00000D000D0CDB7DEB780E060E00E949A1D3C +:1022F0000E94D21E80E060E00E949A1D8BE895E06B +:1023000060E00E94271E80E062E00E949A1D88E73C +:1023100095E060E00E94271E80E063E00E949A1D25 +:1023200082E795E060E00E94271E499BFECF4A9B12 +:10233000FCCF4C9BFACF80E060E00E949A1D0E9487 +:10234000D21E80E062E00E949A1D84E695E060E083 +:102350000E94271E80E063E00E949A1D87E595E0B9 +:1023600060E00E94271E80E064E00E949A1D8AE4DB +:1023700095E060E00E94271E8E010F5F1F4F84ECE6 +:10238000E82E81E0F82EB4E0CB2ED12C16C080913F +:10239000C7358F3F29F08091C7358F5F8093C73550 +:1023A00080E061E20E948B1D6091C73580E00E9451 +:1023B0008B1D80E060E20E948B1D80E060E00E9447 +:1023C0009A1D8FE395E060E00E94271E8091C7353B +:1023D0002DB73EB7285030400FB6F8943EBF0FBE21 +:1023E0002DBFEDB7FEB73196ADB7BEB712961C93B1 +:1023F0000E931197D382C282F582E482868317827C +:102400000E94C2392DB73EB7285F3F4F0FB6F894F0 +:102410003EBF0FBE2DBFC80160E044E50E94A61D6F +:102420008FEF99E6A8E181509040A040E1F700C00D +:102430000000499B04C04A9B02C04C99FACF4A9BBA +:10244000A6CF49990BC08091C735813808F4A8CF31 +:102450008091C73581508093C735A2CF4C99A0CFCA +:102460006091C73581E090E00E940A3C0F900F9088 +:102470000F900F90CF91DF911F910F91FF90EF90F0 +:10248000DF90CF9008951F930E94D21E80E060E0FD +:102490000E949A1D84E393E060E044E50E94A61D3B +:1024A00080E061E00E949A1D8EE995E36EE173E0A1 +:1024B00043E00E94342A882309F48AC080914A03A9 +:1024C000833029F1863019F182E0809358038EE938 +:1024D00095E36BEB75E34FEB55E30E94562388239E +:1024E000D1F487EC94E060E00E94271E8FEF93E226 +:1024F000A4EF81509040A040E1F700C0000010E040 +:102500008EE995E30E943327812F1F91089581E082 +:1025100080935803DCCF80E061E00E949A1D809197 +:102520004A03853009F4BFC0863008F05FC08330AD +:1025300009F4A1C0843039F489EA94E060E00E9493 +:10254000271E80914A0391E0863008F490E0909332 +:1025500075354F998CC0992309F45CC081E0809354 +:10256000540348E754E060E070E08EE995E30E9490 +:102570004B268EE995E365E773E040E052E00E9468 +:10258000C924E0917503F0E0EA58FC4F10821092E4 +:102590008B0380E062E00E949A1D86E793E060E092 +:1025A00044E50E94A61D80E064E00E949A1D8EE42E +:1025B00094E060E00E94271E80915403882379F5FF +:1025C00011E08EE995E30E943327812F1F91089532 +:1025D0008EE995E36EE173E041E00E94342A88239E +:1025E00009F464C081E08093540371CF873009F40B +:1025F00052C0873008F447C0883009F0A4CF8CE57A +:1026000094E060E00E94271E81E080935503809152 +:102610004A0399CF44E254E060E070E0A6CF8DE435 +:1026200060E00E949A1D81E060E00E948B1D81E0C5 +:1026300068E70E948B1D81E06EE70E948B1D81E0A0 +:1026400069E70E948B1D81E069E70E948B1D81E094 +:102650006EE70E948B1D81E068E70E948B1D11E0F0 +:102660008EE995E30E943327812F1F91089581E021 +:102670008093540370CF88EB94E060E00E94271EA3 +:1026800080914A0360CF85E894E060E00E94271EB5 +:1026900080914A0358CF81E794E060E00E94271EB2 +:1026A00080914A0350CF89E994E0ABCF8CED94E060 +:1026B00060E00E94271E1ACF1F931FB7F894E09185 +:1026C0004C03F0E0EE0FFF1FE850F0418081809353 +:1026D0004C030E948A0910924C0310924D031092F1 +:1026E000510310924E0310924F0310925003109218 +:1026F000530382E0809358031092590310925403BD +:10270000109255031092520310925D0310925C03D5 +:102710001092773510927635109295351092943547 +:1027200080E090E0FC01E858FA4C10820196883174 +:102730009105C1F711B8469A28988FE798E3A1E070 +:1027400081509040A040E1F700C0000080B18F7739 +:1027500080935E0346988FE781B9289A8091640040 +:10276000877F8093640083E48093800089E1809375 +:1027700081000E94B0090E94DE1E0E94D21E1FBF6F +:102780001F910895FF920F931F93CF93DF938C01B6 +:10279000F0905203C0917635D09177358DDF0E944D +:1027A000D21E80E060E00E949A1DFF2009F43FC025 +:1027B0008FE196E061E00E94271E80E061E00E94C8 +:1027C0009A1DC80160E044E50E94A61D8DB79EB722 +:1027D00008970FB6F8949EBF0FBE8DBFEDB7FEB73A +:1027E00031960FE513E0ADB7BEB712961C930E936A +:1027F000119786E190E09383828387EC91E0958343 +:102800008483D783C6830E94C2398DB79EB708964A +:102810000FB6F8949EBF0FBE8DBF80E065E00E94AA +:102820009A1DC80160E044E50E94A61DFFCF89E023 +:1028300096E061E00E94271E80E061E00E949A1D00 +:10284000C80160E044E50E94A61DF0CF1F93CF931E +:10285000DF930E94D21E80E060E00E949A1D84EF08 +:1028600095E060E00E94271E4A9BFECF8FEF99E61D +:10287000A8E181509040A040E1F700C000008EE93F +:1028800095E36AEC71E041E00E94342A882331F537 +:1028900062E00E949A1D85EE95E060E00E94271E8E +:1028A00080E063E00E949A1D88ED95E060E00E9460 +:1028B000271E80E065E00E949A1D87EC95E060E0AD +:1028C0000E94271E499B04C04A9B02C04C99FACF24 +:1028D0000E94D21EDF91CF911F9108958EE995E35A +:1028E00065E773E040E052E00E94C92497FD4DC0C7 +:1028F0001092BA351092B93586E195E10E94C93837 +:102900001FB7F8940E947338EC011FBF8EE995E35E +:102910000E94332780E062E00E949A1D209761F1B7 +:10292000ADB7BEB718970FB6F894BEBF0FBEADBF18 +:10293000EDB7FEB731968FE593E012969C938E9398 +:10294000119786E190E09383828387EF91E09583EE +:102950008483D783C6830E94C2398DB79EB70896F9 +:102960000FB6F8949EBF0FBE8DBF8FE593E060E079 +:1029700044E50E94A61D9DCF8FE593E067EE71E0D0 +:1029800046E150E00E94B339F0CF87ED91E0FADEE6 +:10299000AFCF80E060E00E949A1D0E94D21E80E0CE +:1029A00060E00E949A1D8AE295E060E00E94271E86 +:1029B00080E062E00E949A1D87E195E060E00E945D +:1029C000271E80E063E00E949A1D81E195E060E0AF +:1029D0000E94271E499BFECF4A9BFCCF4C9BFACFFF +:1029E00080E062E00E949A1D8DEF94E060E00E941A +:1029F000271E80E063E00E949A1D80EF94E060E073 +:102A00000E94271E8FEF99E6A8E181509040A040D8 +:102A1000E1F700C00000499B04C04A9B02C04C99EA +:102A2000FACF4A9B02C00C94D21E10CF2091B93528 +:102A30003091BA3582E02030380759F0F901EB586F +:102A4000FC4F80812F5F3F4F3093BA352093B935CB +:102A500008958EE995E365E773E040E052E00E9457 +:102A6000C92497FD0BC01092BA351092B93585B1C3 +:102A700098E0892785B920E030E0E0CF87ED91E04C +:102A800081DEF1CF909155039923E1F4E82FF0E036 +:102A9000E45DFE4FE491F0E0262F30E02E173F0773 +:102AA000B4F4AF014F5F5F4F55954795E0FD14C0FB +:102AB00031972E173F0759F06417B0F0862F8F5FBC +:102AC000841B0895262F30E02131310514F080E079 +:102AD0000895862F8F5F0895E42FF0E031972E1729 +:102AE0003F0751F780E00895842F860F0895FF92E5 +:102AF0000F931F938C01F22E0E945520882379F1A9 +:102B0000C80165E773E30E94AD1F882391F1E9ECEA +:102B1000F3E3BF2DBB0FA0E0AB58BC4F81918D9369 +:102B200085E3E537F807D1F7C80165E773E30E944D +:102B3000AD1F882311F1E5E7F3E3BF2DBB0FA0E044 +:102B4000AF5DBA4F81918D9383E3E93CF807D1F7EC +:102B5000C8010E943D201F910F91FF90089588E0C9 +:102B600092E010DEC80165E773E30E94AD1F882381 +:102B700071F68CE192E006DECACF8CE192E002DED3 +:102B8000DACF2F923F924F925F927F928F929F92D5 +:102B9000AF92BF92CF92DF92EF92FF920F931F936B +:102BA000DF93CF93CDB7DEB760970FB6F894DEBF53 +:102BB0000FBECDBF982E792E862E80915503882387 +:102BC00009F4B7C004E210E062E1462E512C80E027 +:102BD00090E020E0FF2458E1E52E46E1A42EB12C40 +:102BE0003CE2C32E32E0D32E1801122F88589A4CA3 +:102BF000DC018C9180FF35C080919035881661F1A1 +:102C0000809190352DB73EB72A5030400FB6F894DA +:102C10003EBF0FBE2DBFEDB7FEB731962FE533E0B7 +:102C2000ADB7BEB712963C932E931197B382A28292 +:102C3000D582C48286821782808711860E94C2391B +:102C40004DB75EB7465F5F4F0FB6F8945EBF0FBEDD +:102C50004DBF8FE593E096DD5E2D583109F466C0D7 +:102C6000F12E1F5F812F90E0821593050CF45AC05E +:102C7000BE2DB83109F43EC080915403882361F41D +:102C800066C0EE2DF0E0E858FA4C80818E7F80839C +:102C900080818B7F8083E394FE1498F7EDB7FEB7B5 +:102CA00038970FB6F894FEBF0FBEEDBF31960FE513 +:102CB00013E0ADB7BEB712961C930E93119786E141 +:102CC00090E09383828381E492E09583848386827B +:102CD00017820E94C239EDB7FEB738960FB6F89446 +:102CE000FEBF0FBEEDBF80E065E024D7C80160E005 +:102CF00044E52CD760960FB6F894DEBF0FBECDBF6B +:102D0000CF91DF911F910F91FF90EF90DF90CF90C7 +:102D1000BF90AF909F908F907F905F904F903F902B +:102D20002F900895183109F4A3CF60CFF12EE12E32 +:102D300098CFE62FF0E0E45DFE4FE4914E2E55244F +:102D40008201000F111F01151105A1F240CFABD672 +:102D5000D6D66B877C878D879E87FE1408F461C169 +:102D6000482D50E05A8749871A01220C331CC101B3 +:102D7000880F991F880F991F880F991F820D931D27 +:102D80009C0140E050E029833A834B835C830E2D05 +:102D9000F101E457FF4F859194919C0140E050E090 +:102DA0002D833E834F8358871E2DAF2C42C08090C9 +:102DB00091352091580330E040E050E069817A81FC +:102DC0008B819C810E940A396B017C018091BB350B +:102DD0009091BC35A091BD35B091BE35C80ED91EBD +:102DE000EA1EFB1E282D30E0429EC001439E900D3E +:102DF000529E900D1124AA2797FDA095BA2FC80EB8 +:102E0000D91EEA1EFB1EC00ED11CE11CF11C2F8531 +:102E10003889322F2227330F2B583C4F892D972D7D +:102E2000B701A6010E947520882371F10F5FA016DB +:102E300088F1402F50E0588B4F87FA01E858FA4C40 +:102E4000808180FDF3CF80915503882309F0AFCFB7 +:102E5000C090BB35D090BC35E090BD35F090BE350C +:102E6000C00ED11CE11CF11C2091580330E040E061 +:102E700050E06D817E818F8198850E940A39C60E4F +:102E8000D71EE81EF91EC3CF86E592E07BDC0F5FFC +:102E9000A01678F6E12EFA2C80915503882309F0CC +:102EA0004FC0F101E457FF4F65917491A090BB357D +:102EB000B090BC35C090BD35D090BE35AE0CB11CC5 +:102EC000C11CD11C80E090E02091580330E040E02C +:102ED00050E00E940A39A60EB71EC81ED91E0F2D3B +:102EE00010E00F5F1F4F0E191109222717FD2095C3 +:102EF000322F892D972DB601A5010E94102288231B +:102F000059F487C0F801E858FA4C80818E7F80839D +:102F100080818B7F8083E394FE14D0F10E2D10E02E +:102F2000B801762F6627770F6B587C4F892D972D28 +:102F30000E949E21882331F789E792E023DCE2CFCB +:102F40008091913590E0489E5001499EB00C589E6A +:102F5000B00C1124CC24B7FCC094DC2C8091BB3580 +:102F60009091BC35A091BD35B091BE35A80EB91E6B +:102F7000CA1EDB1EAE0CB11CC11CD11CB101660FF8 +:102F8000771F660F771F660F771F620D731D9ACF2D +:102F9000892D972D0E945122882309F43EC089E192 +:102FA00080935D0384D5ABD5ADB7BEB71C970FB684 +:102FB000F894BEBF0FBEADBFEDB7FEB731960FE5BB +:102FC00013E012961C930E93119726E130E03383A1 +:102FD00022832AE932E03583248329853A853783A1 +:102FE00026832B853C854D855E85621B730B840B88 +:102FF000950B60877187828793870E94C2394DB78E +:103000005EB7445F5F4F0FB6F8945EBF0FBE4DBF13 +:103010006ACE86E692E0B6DB7FCF88E892E0B2DB4C +:10302000BECF282D30E03A8729871901220C331CA6 +:1030300033CF2F923F924F925F926F927F928F92F7 +:103040009F92AF92BF92CF92DF92EF92FF920F9337 +:103050001F93DF93CF93CDB7DEB7CD54D0400FB6DB +:10306000F894DEBF0FBECDBF18D526DBC1D89AD6E7 +:1030700078948FE79AE1A6E081509040A040E1F774 +:1030800000C0000010D58FE79AE1A6E08150904083 +:10309000A040E1F700C00000499B05C04A9903C069 +:1030A0004C9901C015D989E189831C821C8E1BA211 +:1030B0001EA28E010F5F1F4FC80160E00E94B62A5A +:1030C000882309F49FC42FE5822E23E0922EEFD4AB +:1030D000499905C04A9903C04C9B01C05ADCC801FC +:1030E0000E949B05C8010E94AE07222433248091D0 +:1030F0005203882309F078C0F894D0904C03C09014 +:103100004E0310925103789480915303882309F061 +:103110007EC080915103882351F74B9B04C00799CF +:103120006DC0F1010995499918C080911C039091D7 +:103130001D03009771F3019790931D0380931C0367 +:10314000C8010E94AE078FEF94E3ACE0815090403D +:10315000A040E1F700C00000DCCF4A9B49C04C9979 +:10316000D8CF80914A03813009F4A3C2823009F498 +:1031700038C2809168008860809368008091680000 +:103180008460809368008091680084608093680008 +:103190008091680081608093680010924C030ED685 +:1031A00001D671D9882309F4A2CF8091540391E00C +:1031B000892790915503992309F4826082B9459A31 +:1031C000A7E8B3E11197F1F700C000004598B2E419 +:1031D000BA95F1F700C04298E1E0E0935303809183 +:1031E0005203882309F488CF8FE593E0CBDA84CFAC +:1031F00080911C0390911D0301969ECF89B180FFA1 +:1032000090CF86B180FF8DCF31998DCF8ACFED2CB5 +:10321000FF242DB73EB7285030400FB6F8943EBF7C +:103220000FBE2DBFEDB7FEB73196ADB7BEB7129644 +:103230009C928E92119786E1482E512C53824282A5 +:10324000B6EC6B2EB2E07B2E75826482F782E6824A +:103250000E94C2392DB73EB7285F3F4F0FB6F89492 +:103260003EBF0FBE2DBF88E164E064D4C40160E0BE +:1032700044E56CD4AC2CBB248DB79EB708970FB631 +:10328000F8949EBF0FBE8DBFEDB7FEB73196ADB7B8 +:10329000BEB712969C928E92119753824282ABECEB +:1032A0004A2EA2E05A2E55824482B782A6820E94FC +:1032B000C2392DB73EB7285F3F4F0FB6F8943EBFD7 +:1032C0000FBE2DBF88E364E035D4C40160E044E55F +:1032D0003DD480914D038D1509F45CC160914D037F +:1032E000C8014FDCD0924D03C0924F0380E090E0C4 +:1032F000FC01E858FA4C20812D7F2083019688310B +:103300009105B1F780915103882309F0F0CE8091A7 +:103310005003882309F030C13D2D303598F7809156 +:103320005503882309F05BC1F701E45DFE4F24914A +:1033300080915903821710F01092590386B14B996E +:1033400008C3881F8827881F8EAF2C9D902D1124BD +:1033500023969FAF2397A701440F551FCA01880FDB +:10336000991F880F991F880F991F840F951F289602 +:103370008FAF289729969FAF299730E02A9DC001EB +:103380002B9D900D3A9D900D11242C01662457FC25 +:103390006094762C27964CAE5DAE6EAE7FAE2797CE +:1033A0000E2CEF2C000CEE1CFF08000CEE1CFF1C7A +:1033B000AA0CBB1CA294B29460EFB622BA24A62237 +:1033C000BA245E2C5A285FAE852D90E084589E4F1B +:1033D00044575F4FFA01659074902B967FAE6EAEA6 +:1033E0002B972D2D2F7321962FAF2197E22FF0E0F1 +:1033F000E458FE4F34912C963FAF2C97FC01F4918A +:103400002D96FFAF2D972296DFAE22972E96CFAE48 +:103410002E972401F6B0F094FF1CFF24FF1C09F442 +:1034200013C16EAC6F1461F080E464E083D3FF20BD +:1034300009F42FC182E494E060E009D421E02EAFCA +:1034400080915D03813009F42AC18091550388235E +:1034500009F4ABC0E0905903F8946E2C772458E738 +:10346000852E55E3952E860C971CD4018C9181FDF9 +:103470008FC08C9182FD8CC08C9184608C9381E094 +:103480007894882309F441C080915503882309F07A +:10349000F7C02B966EAD7FAD2B9780915903A0900E +:1034A000BB35B090BC35C090BD35D090BE35A80EB0 +:1034B000B11CC11CD11C27968CAD9DADAEADBFAD6E +:1034C0002797A80EB91ECA1EDB1E80E090E020914F +:1034D000580330E040E050E00E940A39A60EB71EC3 +:1034E000C81ED91EE0D280917535882309F4B7C073 +:1034F000C801B601A5012E2DFADAD9D2D4018C91DA +:1035000082608C938C918B7F8C938091590388235C +:1035100001F5FF2059F085B1B8E08B2785B980917E +:103520005D03823018F0815080935D0320915C032D +:10353000275E20935C032D3708F08CC030E080912B +:103540005A0390915B03821B930B909389008093A5 +:10355000880080915503882379F122E3F22E06C07A +:103560008EE40E94850FFA9409F4BCC08091510347 +:103570008823B1F34201BBCD80E464E0DBD288E470 +:1035800094E060E064D3809151038823E1F3BACEE4 +:1035900080E076CF80915503882309F4B3CE8091E3 +:1035A0004F038C1509F09ACEADCEE09059032396C7 +:1035B0003FAD2397E30E50CFB7E3EB2EF12C0AC0BB +:1035C0008FEF0E94510F0894E108F108E114F10413 +:1035D00009F4EFC080915103882391F3CBCF22E10E +:1035E000A7CE80914B03815080934B03C80161E0CB +:1035F0000E943C2A80914B03882389F0FF249F2D51 +:10360000ADE09A9FB00111246B587E4CC80141E097 +:103610000E945A2AF39480914B03F81680F310927B +:103620001D0310921C03BED3C8010E949B05C80154 +:103630000E94AE078FEF99E6A8E181509040A0402C +:10364000E1F700C0000053CDC80122966FAD22976C +:1036500098DAE7CE10925C0320E030E070CF93015F +:10366000322F2227330F2B583C4FC801B601A5013A +:103670003CD5882309F041CF87ED91E083D83DCF39 +:1036800028969FAD289729968FAD2997692F782F77 +:1036900004CF8CE394E060E0DAD22B9A1EAE109255 +:1036A0005D0380E065E046D286E294E060E0CFD240 +:1036B000CCCEF0904B03AF2DBDE0AB9FC0011124E9 +:1036C0008B589E4C6EE173E04DE050E00E94B339A0 +:1036D000F394F0924B03C8016EE173E041E00E9465 +:1036E0005A2A9DCF9CE0F92E80915103882309F03E +:1036F00041CF0E94850FFA94B9F7EFEFFFEFF093F7 +:103700005703E09356030E94600F0E94600F0E94CF +:10371000600F80915103882309F02CCF8EEF0E9417 +:10372000850F80915103882309F024CF22968FAD15 +:1037300022970E94850F80915103882309F01ACFA8 +:103740002E968FAD2E970E94850F8091510388236E +:1037500009F010CF809159038F5F0E94850F8091EF +:103760005103882309F006CF82E00E94850FF09074 +:1037700056038091570390915103992309F0FACE93 +:103780000E94850F80915103882309F0F3CE8F2D7D +:103790000E94850FFF2408C08EE40E94850FF394D9 +:1037A000FF2DF63109F4F1C0809151038823A1F374 +:1037B000E1CE80915803823009F4E4C0F2E0FF2E9C +:1037C000E090590380915103882309F0D3CE85ED11 +:1037D0000E94510F80915103882309F0CBCE8AEAD1 +:1037E0000E94510F80915103882309F0C3CE86E9CE +:1037F0000E94510F80915103882309F0BBCE2C9673 +:103800008FAD2C970E94510F80915103882309F0AE +:10381000B1CEE0915903F0E0E458FE4F84910E944C +:10382000510F80915103882309F0A4CE2D968FADBE +:103830002D970E94510F80915103882309F09ACE51 +:10384000EF2DF0E0E458FE4F84910E94510F8091DB +:103850005103882309F08ECE2196EFAD2197EE25F6 +:103860002FADE227EF25EF73F0E0E458FE4F84918F +:103870000E94510F80915103882309F07BCE8EED79 +:103880000E94510F80915103882309F073CE8AEA78 +:103890000E94510FEAE0FE2E80915103882309F027 +:1038A00069CE8FEF0E94510FFA94B1F780915103C6 +:1038B000882309F05FCE85ED0E94510F809151035E +:1038C000882309F057CE8AEA0E94510F8091510354 +:1038D000882309F04FCE8DEA0E94510F8091510349 +:1038E000882309F047CEE0915903F0E0E458FE4FF9 +:1038F00084910E94510FC301982F8827990F8B58EC +:103900009C4F0E94AC0F80915103882309F032CE66 +:103910008EED0E94510F80915103882309F02ACE29 +:103920008AEA0E94510F80915103882309F022CE28 +:103930008FEF0E94510F22968FAD2297609159030D +:10394000A1D8809359034B9B65CD2296DFAC22977B +:1039500042014598429A10925303C8016D2D11D926 +:103960008FE79AE1A6E081509040A040E1F700C0C7 +:1039700000000E945C13C8010E949B05C8010E94C0 +:10398000AE07B5CBA2E2FA2E1BCFFF2480915103E4 +:10399000882309F0EFCD0E94850FF3942F2D2C3052 +:1039A000A9F78FEF9FEF90935703809356030E94E0 +:1039B000600F0E94600F0E94600F80915103882366 +:1039C00009F0D8CD8BEF0E94850F6301DC2CCC244D +:1039D000DD0CA5E7B3E0CA0EDB1EEE24FF240AC00F +:1039E0000E94850F0894E11CF11CF0E0EF16F2E054 +:1039F000FF06B9F1F60181916F019091510399236E +:103A000079F3B8CDADB7BEB71A970FB6F894BEBF6D +:103A10000FBEADBFEDB7FEB731969FE5892E93E09F +:103A2000992E12969C928E92119786E190E0938344 +:103A3000828382EB92E095838483898186831782D7 +:103A40008B81808711860E94C239EDB7FEB73A9606 +:103A50000FB6F894FEBF0FBEEDBFC4010E94C213A3 +:103A600036CBF090560380915703909151039923E0 +:103A700009F080CD0E94850F80915103882309F0C1 +:103A800079CD8F2D0E94850F56CF81E090E00C9468 +:103A9000770980E090E00C94770914BC83E085BD41 +:103AA00081E085BB089581E080936E0008951092B7 +:103AB0006E0008951F920F920FB60F9211248F93EC +:103AC0009F93AF93BF938091C3359091C435A091DC +:103AD000C535B091C6350196A11DB11D8093C33582 +:103AE0009093C435A093C535B093C635BF91AF91BF +:103AF0009F918F910F900FBE0F901F9018952FB729 +:103B0000F8946091C3357091C4358091C53590911A +:103B1000C6352FBF089590E59CBD1DBC882341F09C +:103B20005E9A2A986EBD0DB407FEFDCF2A9A0895BD +:103B30005E98F7CF1F93162F682F606880E0EBDF49 +:103B4000612F606480E0E7DF1F910895AF92BF921C +:103B5000CF92DF92EF92FF920F931F93CF93DF9359 +:103B6000D62EC42EE82EF92EBB248FE7A82EF701FF +:103B700001917F01002359F4DF91CF911F910F91A3 +:103B8000FF90EF90DF90CF90BF90AF900895BC145E +:103B900098F70D3609F183E0089F80011124E801B0 +:103BA000CB52DA4F09521A4FFE016491660FD110C1 +:103BB0006A2581E0B0DFB394C017D10749F4BC1483 +:103BC000B0F6DD20C1F16FE781E0A5DFB394CFCF80 +:103BD0002196BC1460F6E8CFDD2079F163E481E042 +:103BE0009ADFB394BC1408F0C2CFDD2051F16BE72B +:103BF00081E091DFB394BC1408F0B9CFDD2029F146 +:103C000067E681E088DFB394BC1408F0B0CFDD2014 +:103C1000D1F06BE781E07FDFB394BC1408F0A7CF4D +:103C2000DD2069F067E481E076DFB394BC1408F02E +:103C30009ECFDD2041F660E0C7CF6CE3D0CF68E3D4 +:103C4000F2CF64E0D5CF64E0E5CF68E1DACFCF9280 +:103C5000DF92EF92FF920F931F93CF93DF93D62EB5 +:103C60008C010F5F1F4F2FE7C22EF8013197E491AF +:103C7000EE2331F1ED3679F183E0E89FF001112474 +:103C8000EF01CB52DA4F98EDE92E95E0F92EEE0ECA +:103C9000FF1EFE016491660FD1106C2581E03BDFB1 +:103CA0002196CE15DF05A9F7DD2099F06FE781E0B9 +:103CB00032DF0F5F1F4FF8013197E491EE23D1F609 +:103CC000DF91CF911F910F91FF90EF90DF90CF90F8 +:103CD000089560E0ECCFDD2089F081E063E41BDF34 +:103CE00081E06BE718DF81E067E615DF81E06BE7D5 +:103CF00012DF81E067E40FDF6FE7D9CF81E06CE38B +:103D00000ADF81E064E007DF81E068E104DF81E051 +:103D100064E001DF81E068E3FEDE60E0C8CFEF929F +:103D2000FF920F931F93CF93DF93E82EF92EF701A5 +:103D300001917F010023E1F00D3609F183E0089F36 +:103D400080011124E801CB52DA4F08521A4FFE01CC +:103D50006491606481E0DFDE2196C017D107B9F776 +:103D600081E060E4D8DEF70101917F01002321F7B3 +:103D7000DF91CF911F910F91FF90EF90089581E017 +:103D80006EE5C9DE81E062E4C6DE81E06CE4C3DE9C +:103D900081E062E4C0DE81E06CE5BDDE81E060E4EC +:103DA000BADEC5CFCF93DF93C8EFD1E081E060E00A +:103DB000B2DE2197D9F7DF91CF9108958FEB8093F1 +:103DC000C73584E18093C83584E08093C935569A1D +:103DD000279A259A229A209A2A98289A8FE798E378 +:103DE000A1E081509040A040E1F700C00000289879 +:103DF0008FE798E3A1E081509040A040E1F700C038 +:103E00000000289A8FE798E3A1E081509040A040FD +:103E1000E1F700C0000080E090E00E94023C813F9A +:103E2000E1F080E090E061EF0E940A3C6091C735CC +:103E300081E090E00E940A3C80E061E26CDE6091EB +:103E4000C73580E068DE6091C83580E064DE80E0E0 +:103E500060E261DE80E06CE05ECE81E090E00E9496 +:103E6000023C8093C735E8CFFC014181842F90E06C +:103E70009C013595279520652CBD40FD06C081E04D +:103E8000463019F08DBD2C98089580E08DBD2C989A +:103E90000895BF92CF92DF92EF92FF920F931F93FC +:103EA000CF93DF938C016B017A0129DEEB01BB24F8 +:103EB000BA94BEBC0DB407FEFDCF8EB5F801828367 +:103EC0008F3FB1F41CDE6C1B7D0B81E06D327807F7 +:103ED00080F381E1F80180832C9A80E0DF91CF911B +:103EE0001F910F91FF90EF90DF90CF90BF900895BA +:103EF0008E3F19F08FE08083EFCFE114F104F1F0F1 +:103F00000894E108F1088FEF8EBDE114F10471F01F +:103F1000F60180E090E03FEF0DB407FEFDCF2EB537 +:103F200021933EBD01968E159F05B0F30DB407FE9B +:103F3000FDCF8EB5F601EE0DFF1D80838FEF8EBD98 +:103F40000DB407FEFDCF8EB58FEF8EBD0DB407FE0D +:103F5000FDCF8EB52C9A81E0C1CF0F931F93CF93E5 +:103F6000DF93EC018B0180DFCE01B80140E052E02D +:103F700090DFDF91CF911F910F910895FF920F93E2 +:103F80001F93CF93DF93EB01BADD8B01FF24FA94EB +:103F9000FEBC0DB407FEFDCF8EB58F3F69F0AFDDDF +:103FA000601B710B6C177D0798F380E0DF91CF9158 +:103FB0001F910F91FF90089581E0DF91CF911F91A4 +:103FC0000F91FF900895DF92EF92FF920F931F934E +:103FD000CF93DF93EC01D62E79018A0145DFCE0124 +:103FE0006CE271E0CBDF8D2D80648EBD0DB407FED9 +:103FF000FDCF28E130E0D801C701022E04C0B695FC +:10400000A795979587950A94D2F78EBD0DB407FEB4 +:10401000FDCF285030408FEF283F380761F7DD2073 +:10402000E9F08D2D883001F587E88EBD0DB407FECF +:10403000FDCF8D2D8C30D1F02FEF9FEF9EBD0DB4B5 +:1040400007FEFDCF8EB58A8387FD0AC0DF91CF9131 +:104050001F910F91FF90EF90DF90089585E9E5CFD4 +:104060002223A1F32150EACF8FEFDFCF8FEF8EBD58 +:104070000DB407FEFDCF8EB5DFCFCF93DF93EC01FC +:10408000F3DECE016CE020E030E0A9019CDF882364 +:1040900039F083E088832C9A80E0DF91CF910895F6 +:1040A0002C9A81E0DF91CF910895CF93DF93EC01BB +:1040B0009A01AB018B81833039F069E0220F331F05 +:1040C000441F551F6A95D1F7CE0162E17CDF88233A +:1040D00039F085E088832C9A80E0DF91CF910895B4 +:1040E0002C9A81E0DF91CF910895CF92DF92EF92E9 +:1040F000FF920F931F93CF93DF93EC017A018B0113 +:1041000069018B81833039F0A9E0EE0CFF1C001FA0 +:10411000111FAA95D1F7CE0161E1A801970153DFE4 +:10412000882369F084E088832C9A80E0DF91CF9126 +:104130001F910F91FF90EF90DF90CF900895CE01E7 +:10414000B60140E052E0A5DEF1CF8F929F92BF9280 +:10415000CF92DF92EF92FF920F931F93DF93CF9353 +:104160000F92CDB7DEB74C01B62EFC011382108240 +:10417000C6DC8B01249A2C9A2698259A279A249A91 +:104180002C9A85E0F401818382E58CBD1DBC8AE018 +:104190009FEF9EBD0DB407FEFDCF8150D1F7C40146 +:1041A00060E020E030E0A9010EDF782FF401828387 +:1041B0008130C9F0A4DC601B710BF7E0613D7F0723 +:1041C00070F381E0F40180832C9A80E00F90CF910E +:1041D000DF911F910F91FF90EF90DF90CF90BF90F4 +:1041E0009F908F900895C40168E02AEA31E040E092 +:1041F00050E07983E8DE798182FF1FC0F401738388 +:10420000CC24DD247601C40167E320E030E0A9017D +:10421000DADEC40169E2A7019601D5DEF4018283EA +:104220008823D9F06CDC601B710BF7E0613D7F07E0 +:1042300050F38AE0F4018083C7CF84E02FEF2EBDD6 +:104240000DB407FEFDCF9EB5F40192838150B9F7FE +:104250009A3A79F082E08083B7CF83818230B1F0DF +:104260002C9AFB2DF73070F088E1F401808380E018 +:10427000ADCF82E0F4018383C12CD12CE12CB0E4DA +:10428000FB2EC1CFF401B18281E0A0CFC4016AE36B +:1042900020E030E0A90197DE882321F088E0F401D6 +:1042A000808392CF8FEF8EBD0DB407FEFDCF8EB50C +:1042B000807C803C19F483E0F401838383E09FEFEA +:1042C0009EBD0DB407FEFDCF2EB58150C9F7C8CFF6 +:1042D000FC016EBDA42FB52F80E090E00DB407FE69 +:1042E000FDCF2C912EBD0DB407FEFDCF11962C9164 +:1042F00011972EBD0296129622E08030920771F738 +:104300000DB407FEFDCF8FEF8EBD0DB407FEFDCFC0 +:104310008FEF8EBD0DB407FEFDCF8FEF8EBD0DB4B8 +:1043200007FEFDCF8EB582838F71853029F083E142 +:1043300080832C9A80E0089581E008950F931F9365 +:10434000CF93DF93EC018B018FDDCE0168E572E046 +:1043500015DE882349F485E188832C9A80E0DF917B +:10436000CF911F910F910895CE016CEFA801B0DF9E +:10437000882389F32C9A81E0DF91CF911F910F91CF +:104380000895CF92DF92EF92FF920F931F93CF93F6 +:10439000DF93EC017A018B0169018B81833039F065 +:1043A00089E0EE0CFF1C001F111F8A95D1F7CE018A +:1043B00068E1A801970107DE882369F086E0888319 +:1043C0002C9A80E0DF91CF911F910F91FF90EF9099 +:1043D000DF90CF900895CE016EEFA60179DF88239C +:1043E00079F3CE0168E572E0C9DD882319F487E12D +:1043F0008883E6CFCE016DE020E030E0A901E3DD67 +:10440000882319F086E18883DBCF8FEF8EBD0DB452 +:1044100007FEFDCF8EB58823A9F72C9A81E0D2CF75 +:10442000AF92BF92CF92DF92EF92FF920F931F93C2 +:10443000CF93DF93EC015A016B017801890167E3A7 +:1044400020E030E0A901BFDDCE0167E1A8019701BE +:10445000BADD882379F089E088832C9A80E0DF91A7 +:10446000CF911F910F91FF90EF90DF90CF90BF9071 +:10447000AF9008958B81833039F099E0AA0CBB1C72 +:10448000CC1CDD1C9A95D1F7CE0169E1A6019501FE +:104490009ADD882319F087E08883DFCF2C9A81E0AA +:1044A000DECFCF93DF93EC01DFDCCE0168E572E075 +:1044B00065DD882359F08DEF8EBD0DB407FEFDCF6D +:1044C000CE0168E572E05ADD882339F482E1888301 +:1044D0002C9A80E0DF91CF9108952C9A81E0DF91B2 +:1044E000CF910895CF93DF93EC019C012C5F3F4F58 +:1044F000898D9A8D41E050E060E070E00E94042DCB +:104500008823D9F08D899E89AF89B88D0097A10540 +:10451000B10579F48C819D81AE81BF818D8B9E8B9D +:10452000AF8BB88F89818068898381E0DF91CF91DB +:10453000089581E0DF91CF91089580E0DF91CF91E0 +:104540000895CF92DF92EF92FF921F93CF93DF9364 +:10455000EC0189899A89AB89BC89803E2FEF92074B +:104560002FE1A20720E0B20748F080E0DF91CF9171 +:104570001F91FF90EF90DF90CF900895CE01B2DFB2 +:10458000882399F30E94D82A882379F3E98DFA8D3C +:10459000CC80DD80EE80FF808EEF9FEFAFEFBFEF2E +:1045A000C80ED91EEA1EFB1E058404C0CC0CDD1CFF +:1045B000EE1CFF1C0A94D2F786859785A089B189E5 +:1045C000C80ED91EEA1EFB1E81E08093D637C0922A +:1045D000D035D092D135E092D235F092D33580E00B +:1045E00092E0E4EDF5E3DF019C011D9221503040A3 +:1045F000E1F7E98DFA8D84818230C0F011E006C0C8 +:104600001F5FE98DFA8D8481181780F4B701A60128 +:10461000410F511D611D711D8091D4379091D53787 +:1046200024ED35E3AEDE882359F79FCF20E032E05A +:1046300040E050E0058404C0220F331F441F551F83 +:104640000A94D2F789899A89AB89BC89820F931F12 +:10465000A41FB51F898B9A8BAB8BBC8B81E086CF57 +:10466000CF93DF93EC018C859D85AE85BF8541E0BE +:10467000662309F440E0BC01CD01DAD7882381F03C +:10468000288930E0220F331F22953295307F322760 +:10469000207F32272C523A4CC901DF91CF910895E7 +:1046A00020E030E0C901DF91CF9108956F927F92B1 +:1046B0008F929F92AF92BF92CF92DF92EF92FF9232 +:1046C0000F931F93DF93CF9300D000D0CDB7DEB709 +:1046D0006C014B013A01DC015596ED90FD900D9176 +:1046E0001C915897E114F10401051105F1F05E01E8 +:1046F0000894A11CB11C10C0D801C7010196A11DCE +:10470000B11D29813A814B815C8182179307A407EF +:10471000B507F9F47C018D01F601818D928DB80108 +:10472000A7019501CAD7882339F780E00F900F9031 +:104730000F900F90CF91DF911F910F91FF90EF900D +:10474000DF90CF90BF90AF909F908F907F906F90B1 +:104750000895D60159966D917C915A97FB018789EE +:10476000803109F44CC0283F8FEF38078FEF48079E +:104770008FE05807D0F2F60185899689A789B08D18 +:104780000297A109B109FB01058404C0880F991F94 +:10479000AA1FBB1F0A94D2F7268537854089518905 +:1047A000820F931FA41FB51FF40180839183A283FE +:1047B000B383FB0186859785A089B1890197A109FB +:1047C000B1092481820F911DA11DB11DA80197017E +:1047D0002250304040405040058404C0220F331F17 +:1047E000441F551F0A94D2F7820F931FA41FB51FB1 +:1047F000F30180839183A283B38381E097CF283F25 +:10480000FFEF3F07F0E04F07F0E05F0708F0B3CF9E +:104810008CCFE82FF92F80E090E03EE209C0DB0169 +:10482000A90FB11D2C939F5F8F5F31968B3061F084 +:1048300020812032C9F3883091F7DB01A90FB11D27 +:104840003C939F5F2081EBCF690F711DFB011082AC +:1048500008951F93FB012BE030E231932150E9F7DB +:10486000A82FB92F30E017E09A2F8B2F2D912223FC +:1048700051F4FA019083818381E0FB0190819032B1 +:1048800079F01F9108952F32A1F32E3261F082E565 +:1048900097E0FC010196E491EE2351F02E17C9F741 +:1048A00080E01F9108951A30D9F338E01AE0DCCF88 +:1048B0001317B0F32132A0F32F3790F7FB01E30F6A +:1048C000F11D822F81568A3108F4205220833F5FE8 +:1048D000CBCF0F931F93CF93DF93EC018B018B8191 +:1048E000882331F4FB018789803141F08032F1F176 +:1048F00080E0DF91CF911F910F91089582E08B832B +:104900001D8A1E8A1F8A188E808D918DA0E0B0E0CE +:10491000880F991FAA1FBB1F880F991FAA1FBB1FB3 +:10492000880F991FAA1FBB1F880F991FAA1FBB1FA3 +:10493000880F991FAA1FBB1F898B9A8BAB8BBC8BCF +:104940001A8F098F81E089831C821D821E821F823B +:10495000188619861A861B861C861D861E861F864B +:10496000188ADF91CF911F910F91089583E08B8377 +:10497000F801428D538D648D758D4D8B5E8B6F8BE1 +:10498000788F9E012F5E3F4FC80124D78823C1F640 +:10499000AFCF2F923F924F925F926F927F928F9202 +:1049A0009F92AF92BF92CF92DF92EF92FF920F93BE +:1049B0001F93CF93DF938C01362FE72F2A01DC0161 +:1049C00013962C911397222329F011968C9111970D +:1049D00080FD16C02FEF3FEFC901DF91CF911F91EE +:1049E0000F91FF90EF90DF90CF90BF90AF909F908E +:1049F0008F907F906F905F904F903F902F90089591 +:104A0000E801C988DA88EB88FC88488559856A8579 +:104A10007B854201AA24BB24D701C601841B950BC8 +:104A2000A60BB70B88169906AA06BB0608F093C01A +:104A30004114510409F4BEC0832E9E2E6201A4E0ED +:104A40002A2E312C200E311E612CF2E07F2E60C008 +:104A5000FF2009F07AC0411551056105710509F083 +:104A6000ABC0E8018D899E89AF89B88D8C839D8309 +:104A7000AE83BF8346855785608971894F0D511D6F +:104A8000611D711D0297A109B109058404C0880F39 +:104A9000991FAA1FBB1F0A94D2F7480F591F6A1FFC +:104AA0007B1FE301CA19DB09CC16DD0608F4E60119 +:104AB000E2E0C030DE0709F452C0CB01BA0140E0A9 +:104AC000B7D5882309F486CF95012C523A4CC401FE +:104AD000B901AE010E949C39AE0160E070E0F801BE +:104AE00080859185A285B385480F591F6A1F7B1F5A +:104AF000D80118964D935D936D937C931B97CC1AB8 +:104B0000DD0A09F457C08C0E9D1E13962C91139745 +:104B1000EFEFAE2EE1E0BE2EA422B5222230B9F195 +:104B2000D8015996ED91FC915A97DB01CA0129E011 +:104B3000B695A795979587952A95D1F7F480FA941D +:104B4000F822A114B10409F483CFE8018C819D817E +:104B5000AE81BF818FCF2601441A550A69CF80915B +:104B6000D0359091D135A091D235B091D335481739 +:104B700059076A077B0709F4A0CF8091D437909139 +:104B8000D5379401B2DA882309F0A6CF23CF39E0D4 +:104B900076956795579547953A95D1F7E801E98D50 +:104BA000FA8D828D938DA48DB58D480F591F6A1F84 +:104BB0007B1F77CF920110CFD80114964D915D9154 +:104BC0006D917C911797CF01910177D5882309F4D6 +:104BD00001CFE801E98DFA8D8C819D81AE81BF8185 +:104BE00049CFDF93CF930F92CDB7DEB7BE016F5F92 +:104BF0007F4F41E050E0CDDE8130910539F02FEF5D +:104C00003FEFC9010F90CF91DF910895298130E0E6 +:104C1000C9010F90CF91DF910895EF92FF920F930A +:104C20001F93CF93DF93EC018B81823050F420E00F +:104C300030E0C901DF91CF911F910F91FF90EF906C +:104C40000895E884F9840A851B85CE01CADF97FDA3 +:104C5000EECF88859985AA85BB854F96A11DB11D8C +:104C600088879987AA87BB87D801C70115E0B695C1 +:104C7000A795979587951A95D1F78F70282F30E0D3 +:104C8000220F331F22953295307F3227207F322723 +:104C90002C523A4CCECF8F929F92AF92BF92CF922E +:104CA000DF92EF92FF920F931F93CF93DF93EC016C +:104CB0004A015B012B81222309F465C089899A8905 +:104CC000AB89BC8984179507A607B70708F45BC0B2 +:104CD000223009F452C081149104A104B10409F4F2 +:104CE0006AC0488559856A857B85E98DFA8D258559 +:104CF00030E0275F3F4FDB01CA010197A109B109ED +:104D0000022E04C0B695A795979587950A94D2F779 +:104D1000850174010894E108F1080109110904C032 +:104D200016950795F794E7942A95D2F7E816F906B1 +:104D30000A071B07B0F58D899E89AF89B88D8C83D2 +:104D40009D83AE83BF8384E0C82ED12CCC0EDD1EA4 +:104D50000FC04C815D816E817F81898D9A8D960116 +:104D6000ACD40894E108F10801091109882359F02D +:104D7000E114F1040105110561F788869986AA8678 +:104D8000BB8681E001C080E0DF91CF911F910F9140 +:104D9000FF90EF90DF90CF90BF90AF909F908F905B +:104DA0000895411551056105710529F2E81AF90ABE +:104DB0000A0B1B0BC8CF1C821D821E821F82188605 +:104DC00019861A861B8681E0DFCF0F931F93CF933E +:104DD000DF93EC018B81882349F0898187FD0EC028 +:104DE000E7D3DF91CF911F910F91089581E08883E0 +:104DF00080E0DF91CF911F910F910895CE0161E086 +:104E00002FDC8C01009791F3FC018081853E71F3CA +:104E10008B818230F8F08D899E89AF89B88DF80139 +:104E2000938F828FB58BA48BE091CC35F091CD35EB +:104E3000309759F0B8016A5E7F4FC80148960995CE +:104E4000F801808D918D938B828B89818F778983F7 +:104E5000AFD3C7CF89899A89AB89BC89848F958F55 +:104E6000A68FB78FD8CFCF93DF93EC01AEDF1B8235 +:104E7000DF91CF9108956F927F928F929F92AF9220 +:104E8000BF92CF92DF92EF92FF920F931F93DF9327 +:104E9000CF9300D000D0CDB7DEB77C015A016B01B3 +:104EA000DC0113968C9113978130A1F080E00F9074 +:104EB0000F900F900F90CF91DF911F910F91FF9066 +:104EC000EF90DF90CF90BF90AF909F908F907F90AA +:104ED0006F90089511968C91119781FFE7CFF7019C +:104EE00081899289A389B48984179507A607B70792 +:104EF000E8F20097A105B10529F1F70160847184FA +:104F000082849384C701B601A501C5DE882371F2AE +:104F1000A114B104C104D104B9F4D70155964D913F +:104F20005D916D917C91589759968D919C915A976E +:104F3000A3D6882309F4BACFF701158A168A178AEF +:104F4000108E40C081E0B3CFD70114964D915D9192 +:104F50006D917C91179759968D919C915A979E01CE +:104F60002F5F3F4FAAD3882309F4A0CFD7015996CA +:104F7000ED91FC915A9749815A816B817C81878997 +:104F80008031C9F1483F8FEF58078FEF68078FE0F6 +:104F90007807C0F4CF0170D6882309F487CFD701F2 +:104FA00014964D915D916D917C91179759968D91C5 +:104FB0009C915A970FEF1FEF2FEF3FE086D4882385 +:104FC00009F474CFF701A18AB28AC38AD48A818195 +:104FD00080688183C701F9DE882309F467CFB601B1 +:104FE000A5016A147B048C049D0410F4B401A30190 +:104FF000C70151DE5CCF483FBFEF5B07B0E06B07F6 +:10500000B0E07B07F8F6C6CF1F93CF93DF93EC0198 +:10501000142FE62FF0E0EE0FFF1FE295F295F07FE0 +:10502000FE27E07FFE27DF01AC52BA4C1B968C9125 +:105030001B97817149F0842F827131F01B8280E0CF +:10504000DF91CF911F9108958091D0359091D13506 +:10505000A091D235B091D3358C879D87AE87BF871D +:10506000688BEC52FA4C84899589A0E0B0E0DC01B1 +:10507000992788278D8B9E8BAF8BB88F428D538D50 +:1050800060E070E0482B592B6A2B7B2B4D8B5E8B9D +:105090006F8B788F838590E0887190700097F1F422 +:1050A000848D958DA68DB78D898B9A8BAB8BBC8BA0 +:1050B00081E08B83812F8F7089831C821D821E82E9 +:1050C0001F82188619861A861B8614FD17C015FDC7 +:1050D0001EC081E0DF91CF911F910895803191052D +:1050E00009F0ACCF9E012F5E3F4F898D9A8D72D310 +:1050F000882309F4A3CF84E08B83DCCFCE0140E08A +:1051000050E0BA01B8DE882311F780E099CF4989D1 +:105110005A896B897C89CE01BEDD92CF8F929F9296 +:10512000AF92BF92CF92DF92EF92FF920F931F93B5 +:10513000CF93DF935C01EB01C42E952E822E898DD7 +:105140009A8DD5015A969C938E935997CB0140E046 +:1051500050E0BA01A0DDDD24E884F9840A851B85CE +:1051600089899A89AB89BC89E816F9060A071B0761 +:1051700008F040C0CE0151DDFC01009709F476C073 +:10518000D801C70115E0B695A795979587951A950B +:10519000D1F7182F1F708081882391F0853E81F010 +:1051A0008C2D992DBF014BE050E00E948F39009764 +:1051B00099F687FC5BC0C501612F482D25DF57C0DC +:1051C000DD20A9F42091D0353091D1354091D235F0 +:1051D0005091D335D5011C962D933D934D935C93FF +:1051E0001F9750961C9350978081DD24D394882379 +:1051F00009F0B2CF86FE3AC081FE38C0DD2009F04A +:1052000043C08B81823091F1CE019BD9882371F10B +:10521000C4EDD5E310E07E01EC2FFF2D80E2DF012D +:105220001D928A95E9F7DE018C2D992DFC018BE00A +:1052300001900D928150E1F7E091CC35F091CD35A0 +:10524000309761F1BE01625F7F4FCE0140960995B4 +:10525000888999892E853F859B8B8A8B998F888F2A +:105260003F8B2E8BA5D1882309F0A5CF80E0DF915D +:10527000CF911F910F91FF90EF90DF90CF90BF9053 +:10528000AF909F908F900895F5011089C50161E05E +:10529000E7D9EC01009709F0BECFE8CF81E298E2B0 +:1052A000998B888B80E098E09F878E8720E038E09C +:1052B00081E298E2D1CF2F923F924F925F926F920C +:1052C0007F928F929F92AF92BF92CF92DF92EF9296 +:1052D000FF920F931F93DF93CF93CDB7DEB7C454E4 +:1052E000D0400FB6F894DEBF0FBECDBF2C013B01FE +:1052F0008E010E5B1F4FD80111965C934E9325963D +:105300002FAF25971C861F861FA21AA6611571054F +:1053100009F45FC0FC018381882309F05AC0CA01E7 +:10532000DA012C912F3209F470C073013CE0832E16 +:10533000912C8C0E9D1E64015E010894A11CB11C71 +:1053400027E2222E312C2C0E3D1EB501A80181DA58 +:10535000882369F1D801ED91FC91119780818F32FA +:1053600041F43196D8011196FC93EE9381918F32DE +:10537000C9F3882309F46FC0C601B701A50121E074 +:10538000CDDE8823A1F0E614F70421F0C7011DDD6E +:10539000F7011382C814D904C9F076016401D80159 +:1053A0008D919C91B501A80154DA882399F600E00B +:1053B0008AA5882321F0CE01879607DD1AA68F855E +:1053C000882341F0CE010C9600DD04C06101740118 +:1053D000E6CF00E0802FCC5BDF4F0FB6F894DEBF46 +:1053E0000FBECDBFCF91DF911F910F91FF90EF9036 +:1053F000DF90CF90BF90AF909F908F907F906F90F5 +:105400005F904F903F902F9008959A012F5F3F4FEC +:10541000C901F80131832083D9014C912F5F3F4F9F +:105420004F32B1F3F30123812250223008F47DCFB3 +:1054300087E2E82EF12CEC0EFD1ED30159966D91FA +:105440007C915A97C70145DA882309F4B0CFF80157 +:10545000808191816BCFC201B701A50125962FAD47 +:1054600025975CDE082FA4CFFB01242F6091CA355D +:105470007091CB35AF011FCF0F931F93CF93DF9365 +:10548000EC01662399F08C010E5D1F4F1093CB3514 +:105490000093CA35C801E7DCBE016C5F7F4FC801CD +:1054A00018DADF91CF911F910F9108958C010E5D55 +:1054B0001F4FF0CFDF92EF92FF920F931F93DF9376 +:1054C000CF93CDB7DEB76C970FB6F894DEBF0FBEA3 +:1054D000CDBFFB01D42E19821C8220812F3229F1ED +:1054E00022E2E22EF12CE80EF91E8E010F5F1F4F13 +:1054F000C801B701AF0121E0DEDE8823F1F08C8125 +:10550000823070F1D701F8018BE101900D9281504A +:10551000E1F7DD2021F0F092CB35E092CA3521E0B1 +:10552000C8012C8FA0DC2C8D0CC021812223C1F658 +:10553000642FA2DF282F8C8102C08C8120E0882379 +:1055400089F4822F6C960FB6F894DEBF0FBECDBFE4 +:10555000CF91DF911F910F91FF90EF90DF90089511 +:1055600020E0EDCF8E010F5F1F4FDACF0F931F9317 +:10557000CF93DF938C010E94A520882331F480E033 +:10558000DF91CF911F910F910895E8012496CE01EC +:10559000B80141E0CDD3882321F0C80161E06CDF80 +:1055A000EFCFCE01B80140E0C3D3882341F3F5CF5C +:1055B0008091D637882311F481E008954091D03549 +:1055C0005091D1356091D2357091D3358091D437D7 +:1055D0009091D53724ED35E30E94C121882321F134 +:1055E0004091D7375091D8376091D9377091DA37D9 +:1055F000411551056105710521F41092D63781E0FE +:1056000008958091D4379091D53724ED35E30E94E9 +:10561000C121882359F01092D7371092D8371092B1 +:10562000D9371092DA37E9CF80E0089580E0089505 +:10563000DF92EF92FF920F931F937B018C01D42E88 +:105640008091D0359091D135A091D235B091D3359C +:105650008E159F05A007B107F1F0AADF882339F462 +:1056600080E01F910F91FF90EF90DF90089580915F +:10567000D4379091D537B801A70124ED35E30E94C6 +:105680007520882369F3E092D035F092D1350093EC +:10569000D2351093D335DD2049F081E08093D637A1 +:1056A0001F910F91FF90EF90DF90089581E01F917F +:1056B0000F91FF90EF90DF900895CF92DF92EF92DD +:1056C000FF920F931F93CF93DF93EC017A018B012D +:1056D000690189859A85AB85BC850196A11DB11D9F +:1056E00084179507A607B70730F0EF89E03169F016 +:1056F000E03209F445C080E0DF91CF911F910F9116 +:10570000FF90EF90DF90CF9008959927872F762F05 +:10571000652F2B893C894D895E89620F731F841F19 +:10572000951F2091D0353091D1354091D23550918F +:10573000D335621773078407950729F040E078DFB7 +:105740008823C9F2EF89E03169F18FE790E0A0E0AA +:10575000B0E0E822F9220A231B23F701EE0FFF1F16 +:10576000EE0FFF1FEC52FA4C80819181A281B38130 +:10577000BF70F60180839183A283B38381E0BCCFA5 +:10578000CB01BA0127E096958795779567952A957D +:10579000D1F72B893C894D895E89620F731F841F65 +:1057A000951FBFCF8FEF90E0A0E0B0E0E822F92294 +:1057B0000A231B23F701EE0FFF1FEC52FA4C8081E6 +:1057C0009181A0E0B0E0F60180839183A283B3834E +:1057D00081E092CF4F925F926F927F928F929F92D1 +:1057E000AF92BF92CF92DF92EF92FF920F931F93EF +:1057F000DF93CF9300D000D0CDB7DEB78C014983C3 +:105800005A836B837C832901842F952FA62FB72F72 +:10581000AC01BD01CC24DD2476015E010894A11CFD +:10582000B11C612CE2E07E2E812C912CC8019501E7 +:1058300044DF882309F447C0D401C301F80105847B +:1058400004C0880F991FAA1FBB1F0A94D2F7C80E65 +:10585000D91EEA1EFB1E49815A816B817C81878992 +:10586000803119F1483F8FEF58078FEF68078FE0BD +:105870007807E0F2F201C082D182E282F38281E015 +:105880000F900F900F900F90CF91DF911F910F917C +:10589000FF90EF90DF90CF90BF90AF909F908F9050 +:1058A0007F906F905F904F900895483FFFEF5F07A4 +:1058B000F0E06F07F0E07F07E8F6C8019501FDDE34 +:1058C000882309F0B9CF80E0DBCF4F925F926F92CF +:1058D0007F928F929F92AF92BF92CF92DF92EF9280 +:1058E000FF920F931F93CF93DF93EC016A017B012B +:1058F00028013901423051056105710590F0898513 +:105900009A85AB85BC850196A11DB11D84179507AD +:10591000A607B70730F08F89803109F456C080326E +:1059200091F080E0DF91CF911F910F91FF90EF9068 +:10593000DF90CF90BF90AF909F908F907F906F90AF +:105940005F904F9008954A015B0117E0B694A794C9 +:10595000979487941A95D1F78B899C89AD89BE89D4 +:10596000880E991EAA1EBB1EC501B40141E060DE6F +:105970008823B9F28F898031A9F18FE790E0A0E008 +:10598000B0E0C822D922EA22FB22F601EE0FFF1F67 +:10599000EE0FFF1FEC52FA4C4082518262827382FA +:1059A0008A89823078F18D819E81AF81B885880D9A +:1059B000991DAA1DBB1D8093D7379093D837A0930C +:1059C000D937B093DA3781E0ADCF852E962EA72E4A +:1059D000BB248B899C89AD89BE89880E991EAA1E1D +:1059E000BB1EC2CF8FEF90E0A0E0B0E0C822D9226A +:1059F000EA22FB22F601EE0FFF1FEC52FA4C518215 +:105A00004082CECF81E08ECF2F923F924F925F9215 +:105A10006F927F928F929F92AF92BF92CF92DF92BE +:105A2000EF92FF920F931F93DF93CF93CDB7DEB723 +:105A300067970FB6F894DEBF0FBECDBF1C01498734 +:105A40005A876B877C873E872D87FC0181859285ED +:105A5000A385B4859C01AD012F5F3F4F4F4F5F4F32 +:105A60002D833E834F835887ED85FE85408051808E +:105A700062807380411451046104710409F4BEC052 +:105A80000894411C511C611C711C1F860097A105C4 +:105A9000B10509F454C0D301C201CC24DD24760140 +:105AA0008E010F5F1F4F4C8A5D8A6E8A7F8A2EC0DF +:105AB0004C015D01C101B501A4019801FEDD8823FF +:105AC00009F43DC089819A81AB81BC810097A10511 +:105AD000B10509F44EC0A50194012F5F3F4F4F4F10 +:105AE0005F4F2C8B3D8B4E8B5F8BDA01C901089485 +:105AF000C11CD11CE11CF11CF101218532854385BB +:105B00005485C216D306E406F506C8F44D805E80BF +:105B10006F807884481659066A067B0648F682E04C +:105B2000882E912CA12CB12C8C8A9D8AAE8ABF8A9A +:105B3000C101B501A4019801C0DD882319F680E0F8 +:105B400067960FB6F894DEBF0FBECDBFCF91DF9141 +:105B50001F910F91FF90EF90DF90CF90BF90AF908B +:105B60009F908F907F906F905F904F903F902F907D +:105B70000895D501C4010196A11DB11D2C013D015F +:105B80002C893D894E895F89421A530A640A750A35 +:105B900029853A854B855C85421653066406750651 +:105BA00009F0A5CF4C885D886E887F88C101B5015A +:105BB000A4010FEF1FEF2FEF3FE087DE882309F4EA +:105BC000BECF481459046A047B0458F5950184013A +:105BD00007C0970186014C145D046E047F0408F52C +:105BE000680179010894C108D108E108F108C101F0 +:105BF000B701A6016ADE882361F7A1CFF1014080D9 +:105C0000518062807380F1E0FF8729853A854B855A +:105C10005C85213031054105510509F437CF1F86D8 +:105C200035CFAD85BE854D915D916D917C9113977A +:105C30004115510561057105C1F4ED85FE85408270 +:105C4000518262827382FF85FF2369F00894411CB0 +:105C5000511C611C711CD1014D925D926D927C9220 +:105C6000139781E06DCF81E06BCFC1019301820179 +:105C70002CDE882311F763CFAF92BF92CF92DF92D1 +:105C8000EF92FF920F931F93DF93CF9300D000D03A +:105C9000CDB7DEB76C017A018B0182E090E0A0E025 +:105CA000B0E0F60180839183A283B3835E01089400 +:105CB000A11CB11CC601B801A7019501FEDC882317 +:105CC00039F1C601B801A70100E010E09801FDDD3F +:105CD0008823F1F0E980FA800B811C81F601878925 +:105CE000803159F088EFE8168FEFF8068FEF08073C +:105CF0008FE01807F8F281E00CC0F8EFEF16FFEF25 +:105D0000FF06F0E00F07F0E01F07A0F281E001C0FE +:105D100080E00F900F900F900F90CF91DF911F9127 +:105D20000F91FF90EF90DF90CF90BF90AF900895CC +:105D30006F927F928F929F92AF92BF92DF92EF927B +:105D4000FF920F931F93CF93DF93EC01142F709367 +:105D5000D5376093D4371F8A82E090E0A0E0B0E0AE +:105D600088839983AA83BB831092D6371092D73742 +:105D70001092D8371092D9371092DA378FEF9FEF01 +:105D8000DC018093D0359093D135A093D235B09378 +:105D9000D335442309F444C0453078F080E0DF91E6 +:105DA000CF911F910F91FF90EF90DF90BF90AF9038 +:105DB0009F908F907F906F90089560E070E0CB018E +:105DC00040E036DC882351F3212F30E022953295D4 +:105DD000307F3227207F32272C533A4CF901E2548E +:105DE000FE4F808190E08F7790700097B9F6F901AF +:105DF000E653FE4F80819181A281B3818436910563 +:105E0000A105B10558F22A533E4FF901E080F18017 +:105E100002811381E114F1040105110521F4BECFC3 +:105E2000EE24FF248701C801B70140E001DC88238C +:105E300009F4B4CF8091DF359091E035F2E0803005 +:105E40009F0709F0ABCF2091E435222309F4A6CFB8 +:105E50008091E2359091E335009709F49FCF6091EE +:105E6000E135662309F49ACF2A8B6C831D8670E096 +:105E700080E090E041E050E008C0282F2F5F2D87A0 +:105E800001968930910509F489CFD82E9A01082E00 +:105E900002C0220F331F0A94E2F72617370769F76B +:105EA0006091EA357091EB356115710509F47FC099 +:105EB00080E090E06D837E838F8398878090E235C9 +:105EC0009090E335AA24BB248E0C9F1CA01EB11E0B +:105ED0008B8A9C8AAD8ABE8A6090E5357090E635E3 +:105EE000798E688E2091E43530E040E050E00E94E9 +:105EF0000A39680D791D8A1D9B1D6A8F7B8F8C8FD7 +:105F00009D8F9301220F331F22953295307F3227C8 +:105F1000207F322721503E4F232F3327269540E004 +:105F200050E0260F371F481F591F2E873F87488B89 +:105F3000598B8091E7359091E835009709F440C07E +:105F4000A0E0B0E0E21AF30A040B150BE80EF91E0C +:105F50000A1F1B1F04C016950795F794E794DA945F +:105F6000D2F7E986FA860B871C8725EFE2162FE029 +:105F7000F20620E0020720E0120758F185EFE8164C +:105F80008FEFF80680E0080780E0180730F1809175 +:105F9000003690910136A0910236B09103368A8F77 +:105FA0009B8FAC8FBD8F80E28F8B81E0F8CE6091AC +:105FB000F8357091F9358091FA359091FB357ACFAB +:105FC0008091F4359091F535A091F635B091F73583 +:105FD000B9CF8CE08F8B80E0E2CE80E18F8B81E0C7 +:105FE000DECECF93DF93DC01CD91DC9111971C16AF +:105FF0001D06DCF41296E0E0F0E020E030E0A901BC +:10600000542F432F322F22276D9170E080E090E0D3 +:10601000262B372B482B592B3196EC17FD0781F790 +:10602000B901CA01DF91CF91089520E030E0A901C4 +:10603000F7CFCF93DF93FB01DC012D913C91B901A8 +:106040006E5F7F4FEC01C60FD71FE60FF71FD90118 +:106050001196A40FB51F2115310599F0215030403C +:106060008A9192914115510519F06C9186239623DE +:106070001197891781F320E030E0C901DF91CF91BA +:10608000089521E030E0C901DF91CF910895CF93C9 +:10609000DF93FB0120813181DC012D933C93A081B2 +:1060A000B181109701F1BD01615070401296EA0F65 +:1060B000FB1FEA01CA0FDB1FA80FB91F80E09A91EE +:1060C000229130E0290F311D280F311D81E02F3F33 +:1060D000310509F008F480E02E93615070409FEF85 +:1060E0006F3F790761F7DF91CF910895EF92FF92AB +:1060F0000F931F93CF93DF938B01FC017183608318 +:106100006115710581F022E0E22EF12CE80EF91EF6 +:10611000C0E0D0E0C7018C0F9D1F0E94CE382196B1 +:10612000C017D107B9F7DF91CF911F910F91FF9061 +:10613000EF90089524E030E0FC013783268384E06B +:1061400090E0089521E0FC01208380E090E0089534 +:10615000EF92FF920F931F93DF93CF930F92CDB7E0 +:10616000DEB77C018E010F5F1F4FC8010E94CE3841 +:1061700089818823D1F7F7011782168280E090E0A9 +:106180000F90CF91DF911F910F91FF90EF900895A5 +:106190000F931F93DF93CF930F92CDB7DEB78C0190 +:1061A000CE010196FBD78981823070F085E090E0C6 +:1061B000F8019783868325E030E0C9010F90CF91E5 +:1061C000DF911F910F910895F8019181933141F072 +:1061D000882369F481E0F801828720E030E0EDCF88 +:1061E000882359F481E0818720E030E0E6CF86E023 +:1061F000F801828720E030E0E0CF8DE0F801818770 +:1062000020E030E0DACF0B96C9D780E090E0089527 +:10621000CF93DF93EC016C897D898E559F4F66DFAC +:106220006C897D89CE018B539F4F60DF80E090E0C9 +:10623000DF91CF910895FC016489758981589F4F42 +:1062400055DF80E090E008950F931F93CF93DF9385 +:106250008C01EC016696CE0164E070E047DFCE0170 +:10626000C0DEF801648775878687978780E090E0B5 +:10627000DF91CF911F910F9108950F931F93CF93AB +:10628000DF938C01EC016696CE0164E070E02EDFB6 +:10629000CE01A7DEF801608B718B828B938B695FD7 +:1062A0007F4F8F4F9F4F28E030E040E050E00E944A +:1062B0005F39F801358B248B2132310564F086E09B +:1062C00090E09783868326E030E0C901DF91CF918B +:1062D0001F910F91089520E030E0C901DF91CF9127 +:1062E0001F910F910895BC0181E090E02BD780E0D1 +:1062F00090E060E070E026D780E090E061E070E040 +:1063000021C74F925F926F927F928F929F92AF922E +:10631000BF92CF92DF92EF92FF920F931F93CF9392 +:10632000DF93EC01F62E662309F4A4C0888186175A +:1063300009F4EEC06730C1F06E30C1F48D30B1F0B9 +:1063400005E010E0C801DF91CF911F910F91FF9000 +:10635000EF90DF90CF90BF90AF909F908F907F9005 +:106360006F905F904F900895863051F700E010E0F5 +:10637000A8E0AA2EFCE0CF2EEEE06E2E7FE0B72E36 +:1063800062E0E62E992493945AE0752E45E0D42ECF +:1063900037E0832E23E0422E99E0592EF81691F231 +:1063A000873009F495C08830A8F4833009F453C0CD +:1063B000843008F03CC08130A1F1823008F454C030 +:1063C0008F2D893008F49EC081E090E08CDF5882E8 +:1063D0008881E4CF8B3059F08C3078F4893009F41F +:1063E00067C08A3008F47DC09F2D9B3089F081E022 +:1063F00090E079DFC8828881D1CF8D3009F452C016 +:106400008D3000F18E3009F075C09F2D9B30E9F47E +:1064100080E090E068DFF8828881C0CF8F2D8130E6 +:1064200019F181E090E05FDFE8828881B7CF8530A5 +:1064300009F444C0863090F081E090E054DF888217 +:106440008881ACCF8F2D8D3019F381E090E04BDF48 +:10645000B8828881A3CF9F2D9430D1F281E090E063 +:1064600042DFD88288819ACF80E090E03CDF98823A +:10647000888194CF81E090E036DF00E010E080E09A +:1064800090E060E070E05ED680E090E061E070E077 +:1064900059D60F5F1F4F0530110589F7188200E0AC +:1064A00010E050CF81E090E01EDF6882888176CFD7 +:1064B00080E090E018DF7882888170CF8F2D863061 +:1064C00009F4A6CF81E090E00EDFA882888166CF34 +:1064D0009F2D943009F49CCF81E090E004DFA882E6 +:1064E000F5CF8F2D813009F493CF81E090E0FBDE72 +:1064F000E8829BCF8F3009F491CFF88205E010E05D +:1065000088814CCF80E090E0EEDE4882888146CFE3 +:10651000863049F08D3009F029CF81E090E0E3DE4C +:106520008EE0888323CF81E090E0DDDE87E0888302 +:106530001DCFCF92DF92EF92FF920F931F93CF93D5 +:10654000DF93EC018C010A5E1F4FC80161E070E02F +:10655000CDDDC88CC80161E070E0C8DDD88CC80111 +:1065600064E070E0C3DDC8013CDD7B018C018885FF +:106570008C1521F0CE0108966C2DC3DEC801B70141 +:1065800023D688858D1521F0CE0108966D2DB9DEB4 +:1065900080E090E0DF91CF911F910F91FF90EF90FD +:1065A000DF90CF9008950F931F93DF93CF930F92B7 +:1065B000CDB7DEB78C01CE010196F0D5C8010896A3 +:1065C00069819FDE9C01009719F0F801978386830B +:1065D000C9010F90CF91DF911F910F9108954F92B4 +:1065E0005F926F927F928F929F92AF92BF92CF9263 +:1065F000DF92EF92FF920F931F93CF93DF935B0194 +:106600006C01FA0138012115310509F481C080813E +:106610009181D90111969C938E93808191818C01F7 +:106620000E5F1F4F020F131FA114B104C104D10448 +:1066300009F45DC022E0422E512C480E591E4E0E28 +:106640005F1E0CC00115110519F0D8019E928D0135 +:10665000A114B104C104D10409F449C0F20182902B +:106660002F01EE24FF2499240894A108B108C10841 +:10667000D1086114710429F0A114B104C104D1043A +:1066800081F1C82DD0E0BE016170707082E090E0B1 +:1066900059D580E090E060E070E054D50115110517 +:1066A00049F08ED590E00E2C02C0880F991F0A94F5 +:1066B000E2F7982A80E090E061E070E043D5A11411 +:1066C000B104C104D10409F4BDCF0894E11CF11C4C +:1066D000F8E0EF16F10409F4B5CFD595C7958C2EE7 +:1066E000C3CF81E090E061E070E02CD5CACFDF91AC +:1066F000CF911F910F91FF90EF90DF90CF90BF90BF +:10670000AF909F908F907F906F905F904F90089583 +:106710008081918100E010E087CF2F923F924F92CD +:106720005F926F927F928F929F92AF92BF92CF9221 +:10673000DF92EF92FF920F931F93DF93CF93CDB72A +:10674000DEB728970FB6F894DEBF0FBECDBF3C0171 +:10675000962E29833A834B835C831E830D83170116 +:106760002601B886AF82A9A051E0C52ED12C6815AC +:1067700009F487C029813A814B815C81211531055B +:106780004105510529F58D8D9E8DAF8DB8A10097DE +:10679000A105B10509F097C020E030E0C9012896B5 +:1067A0000FB6F894DEBF0FBECDBFCF91DF911F9122 +:1067B0000F91FF90EF90DF90CF90BF90AF909F90A0 +:1067C0008F907F906F905F904F903F902F900895A3 +:1067D000BB24EE24FF24C301692D93DD69817A81F6 +:1067E0008B819C814D815E8191018601F8DE41148F +:1067F000510461F0C201B1014F8158851ADC41E0BA +:10680000E42EF12C009711F0EE24FF24C114D104E2 +:10681000E9F0D3018C918F5F8C93E114F10459F06E +:106820002D8D3E8D4F8D58A1211531054105510506 +:1068300011F0BA1448F1C301682D63DD8D8D9E8D72 +:10684000AF8DB8A10097A105B10591F4E114F10451 +:1068500009F4A2CFB3948B2D81508A1508F4BBCFD5 +:10686000AA2019F0AB1408F439C022E030E096CF2A +:10687000C30161E046DD6D8D7E8D8F8D98A1A4D41E +:10688000E5CFCC24DD2476CFC30166E03ADDC30139 +:1068900064E037DD8D8D9E8DAF8DB8A1B595A79540 +:1068A00097958795B595A795979587952D8D3E8D4D +:1068B0004F8D58A1280F391F4A1F5B1F2D8F3E8F08 +:1068C0004F8F58A3BBCFC30161E01BDD6D8D7E8D63 +:1068D0008F8D98A179D420E030E060CF23E030E0C4 +:1068E0005DCF8F92AF92BF92CF92DF92EF92FF92E5 +:1068F0000F931F93CF93DF93EC018C010A5E1F4F20 +:106900006C897D89C801F2DB00D000D00F92288904 +:1069100039894A895B89ECE5EE2EF12CEC0EFD1EDF +:1069200079E3C72ED12CCC0EDD1E6FE7A62EB12C3D +:10693000AC0EBD1E8C859D85AE85BF85EDB7FEB7BF +:1069400081839283A383B4838B858583CE0108964C +:1069500064E08A84E2DE9C010F900F900F900F900C +:106960000F90009711F09F838E83C901DF91CF9123 +:106970001F910F91FF90EF90DF90CF90BF90AF905D +:106980008F9008958F92AF92BF92CF92DF92EF9245 +:10699000FF920F931F93CF93DF93EC018C010A5E5C +:1069A0001F4FC80162E070E0A1DBC8011ADB6B0178 +:1069B0007C01695F7F4F8F4F9F4F28E030E040E0C0 +:1069C00050E07DD4213231058CF026E030E03F8369 +:1069D0002E83C901DF91CF911F910F91FF90EF900E +:1069E000DF90CF90BF90AF908F900895C801B9010C +:1069F0007DDB00D000D00F928C859D85AE85BF8554 +:106A0000EDB7FEB781839283A383B4831582CE0151 +:106A100008966BE0A7019601EE24FF24CC24DD2428 +:106A2000AA24BB24898479DE9C010F900F900F90DB +:106A30000F900F90009769F2CACF6F927F928F925A +:106A4000AF92BF92CF92DF92EF92FF920F931F937C +:106A5000DF93CF930F92CDB7DEB73C01CE01019605 +:106A60009DD383010A5E1F4F298130E040E050E052 +:106A7000295F3F4F4F4F5F4FF3E05595479537954F +:106A80002795FA95D1F7C801B90130DB00D000D0C5 +:106A90000F92298130E040E050E0F3018485958534 +:106AA000A685B785EDB7FEB781839283A383B483B0 +:106AB0001582C30108966BE0EE24FF24CC24DD246C +:106AC000AA24BB24F301818428DE9C010F900F903F +:106AD0000F900F900F90009719F0F3019783868322 +:106AE000C9010F90CF91DF911F910F91FF90EF900F +:106AF000DF90CF90BF90AF908F907F906F90089570 +:106B00002F923F924F925F926F927F928F92AF92AD +:106B1000BF92CF92DF92EF92FF920F931F93DF937A +:106B2000CF9300D0CDB7DEB79A8389831A012B01AA +:106B30003901C801B901DADAC114D10419F0C6016A +:106B4000B301D4DA00D000D00F928E899F89A88D2E +:106B5000B98DEDB7FEB781839283A383B4838A8D09 +:106B6000858389819A8164E0A2019101D6DD0F902D +:106B70000F900F900F900F900F900F90CF91DF918B +:106B80001F910F91FF90EF90DF90CF90BF90AF904B +:106B90008F907F906F905F904F903F902F900895CF +:106BA0008F92AF92BF92CF92DF92EF92FF920F93AC +:106BB0001F93CF93DF93EC0189818131D9F114E0E8 +:106BC000812E00D000D00F92488959896A897B892B +:106BD0002C893D898E010A5E1F4FBCE5EB2EF12CFE +:106BE000EC0EFD1EA9E3CA2ED12CCC0EDD1EEDB796 +:106BF000FEB711821282138214821582CE0108968A +:106C0000AA24BB247DDF9C010F900F900F900F9062 +:106C10000F90009711F09F838E83C901DF91CF9170 +:106C20001F910F91FF90EF90DF90CF90BF90AF90AA +:106C30008F9008958A84C5CF8F92AF92BF92CF92E2 +:106C4000DF92EF92FF920F931F93CF93DF93EC01AC +:106C500089818E30A9F104E0802E00D000D00F92FF +:106C6000488959896A897B892C893D898E010A5E08 +:106C70001F4FEDB7FEB71182128213821482158264 +:106C8000CE010896EE24FF24CC24DD24AA24BB24C4 +:106C900037DF9C010F900F900F900F900F9000978F +:106CA00011F09F838E83C901DF91CF911F910F91C6 +:106CB000FF90EF90DF90CF90BF90AF908F900895AE +:106CC0008A84CBCF8F92AF92BF92CF92DF92EF9216 +:106CD000FF920F931F93CF93DF93EC0100D000D06E +:106CE0000F92488959896A897B892C893D898C0151 +:106CF0000A5E1F4FECE5EE2EF12CE80EF91E99E32B +:106D0000C92ED12CCC0EDD1E8FE7A82EB12CAC0ED7 +:106D1000BD1E8C859D85AE85BF85EDB7FEB7818391 +:106D20009283A383B4838B858583CE0108968A845E +:106D3000E7DE9C010F900F900F900F900F9000973F +:106D400011F09F838E83C901DF91CF911F910F9125 +:106D5000FF90EF90DF90CF90BF90AF908F9008950D +:106D6000CF92DF92EF92FF920F931F93CF93DF9317 +:106D70008C016B017901B8018AD9E601288139813A +:106D8000F701A081B181AD014150504057FD38C09D +:106D9000FD013296EE0DFF1D1196A00FB11F60E0B0 +:106DA00010E08291882329F1EC9001E00AC0762F4F +:106DB000660F7123B1F0E02A959587958823C1F07D +:106DC000000F90E080FFF8CF662389F72150304014 +:106DD000B601620F731FEB011A8162E071E071234B +:106DE00051F7702F7095E72295958795882341F785 +:106DF000EC924150504011978FEF4F3F580789F662 +:106E0000DF91CF911F910F91FF90EF90DF90CF9086 +:106E100008952F923F924F925F926F927F928F923E +:106E20009F92AF92BF92CF92DF92EF92FF920F9319 +:106E30001F93DF93CF93CDB7DEB761970FB6F8946A +:106E4000DEBF0FBECDBF3C01B6E14B2E512C480E2C +:106E5000591EFC0164897589C20148D9C30108968D +:106E60009D838C83F301E45AFF4FFF83EE83C301BC +:106E7000C99699878887AFE72A2E312C260C371CB4 +:106E800000D000D00F92F3012089318942895389C3 +:106E900084859585A685B785EDB7FEB781839283F6 +:106EA000A383B483F3018385EDB7FEB785838C811B +:106EB0009D8164E08201EE80FF80C884D984510105 +:106EC000F30182842ADC9B838A830F900F900F90BA +:106ED0000F900F90009709F087C0C3018B539F4F0D +:106EE0009D878C87FC0140815181141615060CF09A +:106EF0009DC0E0E0F0E060E000E010E0E60DF71D8E +:106F0000E953FF4F8081882351F090E09C0121706C +:106F10003070020F131F959587958823B1F76F5F27 +:106F2000E62FF0E0E417F5074CF3CE01019636D1D9 +:106F3000222717FD2095322F095F1F4F2F4F3F4FFC +:106F4000E3E03595279517950795EA95D1F71F87C3 +:106F50000E879924C30188519F4F9B878A87F3012D +:106F6000EE55FF4FF98BE88B8981981608F043C0E6 +:106F70008A859B856E857F85B9D8C2016A857B85A8 +:106F8000488959892C853D85EBDE00D000D00F92D1 +:106F9000F301208931894289538984859585A685A5 +:106FA000B785EDB7FEB781839283A383B483F301E2 +:106FB0008385EDB7FEB785838C819D8164E0820176 +:106FC000EE80FF80C884D9845101F3018284A5DB5F +:106FD0000F900F900F900F900F90009739F49394AB +:106FE0008981981640F4C4CF8A819B81F3019783ED +:106FF00086839B838A838A819B8161960FB6F894EE +:10700000DEBF0FBECDBFCF91DF911F910F91FF90DB +:10701000EF90DF90CF90BF90AF909F908F907F9038 +:107020006F905F904F903F902F90089500E010E098 +:107030007CCFCF93DF93EC01188219821A821B82D6 +:107040001C821D821F821E821B86188681E0898712 +:107050008A87188A198A1A8A1B8A1D8A1C8A1C86A2 +:107060001D861E861F86CE01089660E04AD98E8353 +:107070009F83DF91CF910895CF93DF93EC012E8111 +:107080003F812115310519F48881882321F0C90138 +:10709000DF91CF910895CE01019680D08A819B81A6 +:1070A000AC81BD810196A11DB11D8A839B83AC83F8 +:1070B000BD83E981E83150F084E090E09F838E83C6 +:1070C00024E030E0C901DF91CF910895F0E0EE0FA8 +:1070D000FF1FE851FD4F0190F081E02DCE01099591 +:1070E0002E813F81D4CF0F931F93DF93CF93CDB7E2 +:1070F000DEB7CB50D1400FB6F894DEBF0FBECDBF88 +:107100008E010F5F1F4FC80194DF2F813885211535 +:10711000310569F0C901C55FDE4F0FB6F894DEBFD7 +:107120000FBECDBFCF91DF911F910F91089589813F +:10713000882381F7C801A0DF2F813885211531050B +:10714000B1F3E8CF8130910551F08230910561F0C3 +:10715000009721F46115710571F442980895611545 +:10716000710539F0439A08956115710531F0459A1A +:10717000089543980895429A08954598089580E0A7 +:1071800090E060E070E0DEDF80E090E061E070E0E1 +:10719000D9CF9093DC378093DB370895CF93DF937B +:1071A000EC01E091DB37F091DC37309729F009955D +:1071B0008883DF91CF9108951882DF91CF91089550 +:1071C00081E0349B80E00895AF92BF92CF92DF922E +:1071D000EF92FF920F931F935B016C011616170637 +:1071E0001806190674F4EE24FF248701C8DF0894FA +:1071F000E11CF11C011D111DEA14FB040C051D0509 +:10720000ACF31F910F91FF90EF90DF90CF90BF9064 +:10721000AF900895629FD001739FF001829FE00DAF +:10722000F11D649FE00DF11D929FF00D839FF00D05 +:10723000749FF00D659FF00D9927729FB00DE11DB1 +:10724000F91F639FB00DE11DF91FBD01CF0111248E +:107250000895AA1BBB1B51E107C0AA1FBB1FA6179D +:10726000B70710F0A61BB70B881F991F5A95A9F7EF +:1072700080959095BC01CD010895A1E21A2EAA1B1C +:10728000BB1BFD010DC0AA1FBB1FEE1FFF1FA217D6 +:10729000B307E407F50720F0A21BB30BE40BF50BD3 +:1072A000661F771F881F991F1A9469F7609570955C +:1072B000809590959B01AC01BD01CF01089597FB8E +:1072C000092E05260ED057FD04D0D7DF0AD0001CAA +:1072D00038F450954095309521953F4F4F4F5F4F73 +:1072E0000895F6F790958095709561957F4F8F4F33 +:1072F0009F4F08950790F691E02D099491110895FC +:1073000081568A5108F4805285580895FC010590F1 +:107310000020E9F7809590958E0F9F1F0895FB013F +:10732000DC0104C08D910190801921F4415050403E +:10733000C8F7881B990B0895FB01DC0102C001907E +:107340000D9241505040D8F70895FB01DC014150A7 +:10735000504030F08D910190801919F40020B9F758 +:10736000881B990B0895FB01DC014150504048F007 +:1073700001900D920020C9F701C01D92415050406C +:10738000E0F708950F931F93DF93CF93CDB7DEB748 +:107390002E970FB6F894DEBF0FBECDBF0D891E89A4 +:1073A0008F89988D26E02C831A83098397FF02C06A +:1073B00080E090E801979E838D839E01255E3F4F7C +:1073C000CE010196698D7A8DA90119D04D815E811A +:1073D00057FD0AC02F813885421753070CF49A01D4 +:1073E000020F131FF80110822E960FB6F894DEBF1D +:1073F0000FBECDBFCF91DF911F910F9108952F92B6 +:107400003F924F925F926F927F928F929F92AF9234 +:10741000BF92CF92DF92EF92FF920F931F93DF9371 +:10742000CF93CDB7DEB72C970FB6F894DEBF0FBE63 +:10743000CDBF6C011B018A01FC011782168283817A +:1074400081FFC4C12E010894411C511CF601938197 +:10745000F10193FD859193FF81911F01882309F428 +:10746000B1C1853239F493FD859193FF81911F015C +:10747000853221F490E0B601F5D1E8CFEE24FF2467 +:1074800020E02032B0F48B3269F08C3228F4803264 +:1074900051F0833271F40BC08D3239F0803349F4EE +:1074A00021602CC02260246029C0286027C0206190 +:1074B00025C027FD2CC0382F30533A3098F426FFD2 +:1074C00008C08E2D880FE82EEE0CEE0CE80EE30EB1 +:1074D00015C08F2D880FF82EFF0CFF0CF80EF30E41 +:1074E00020620CC08E3221F426FD6CC1206406C0DF +:1074F0008C3611F4206802C0883649F4F10193FDFE +:10750000859193FF81911F01882309F0BACF982FAD +:107510009554933018F09052933028F40C5F1F4F1D +:10752000FFE3F9830DC0833631F0833771F0833583 +:1075300009F05CC021C0F801808189830E5F1F4F74 +:10754000420171E0A72EB12C15C062E0662E712CAD +:10755000600E711EF8018080918026FF03C06E2DA1 +:1075600070E002C06FEF7FEFC4012C8770D15C0127 +:1075700083012C852F7716C052E0652E712C600E8A +:10758000711EF8018080918026FF03C06E2D70E08F +:1075900002C06FEF7FEFC4012C874ED15C012C85B8 +:1075A0002068830123FD1EC007C080E290E0B60181 +:1075B0002C8758D1FA942C858F2D90E0A816B90607 +:1075C000A0F310C0F40127FD859127FF81914F01A1 +:1075D00090E0B6012C8746D12C85F110FA940894DE +:1075E000A108B108A114B10469F7E9C0843611F00B +:1075F000893641F527FF08C0F801608171818281D9 +:1076000093810C5F1F4F09C0F80160817181882749 +:1076100077FD8095982F0E5F1F4F4FE6B42EB22254 +:1076200097FF09C090958095709561957F4F8F4F1A +:107630009F4FF0E8BF2AA2012AE030E03FD1782E28 +:10764000741844C0853731F43FEEB32EB2222AE0DD +:1076500030E025C099EFB92EB2228F36C1F08037C5 +:1076600020F4883509F0AEC00DC0803721F088378E +:1076700009F0A8C002C020E1B22AB4FE0BC084E029 +:10768000B82A08C0B4FE09C0E6E0BE2A06C028E059 +:1076900030E005C020E130E002C020E132E0B7FE7A +:1076A00008C0F80160817181828193810C5F1F4F56 +:1076B00007C0F8016081718180E090E00E5F1F4F8C +:1076C000A201FCD0782E7418FFE7BF22B6FE0BC0D3 +:1076D0002EEFB2227E1438F4B4FE07C0B2FC05C00F +:1076E0008FEEB82202C0A72C01C0AE2C8B2D90E0EB +:1076F000B4FE0DC0FE01E70DF11D2081203319F409 +:10770000E9EEBE2209C0A394B2FE06C004C086788A +:107710009070009709F0A3948B2C9924B3FC13C0AC +:10772000B0FE0EC0AF1428F4E72CEF0CEA18AF2C13 +:1077300007C0E72C05C080E290E0B60193D0A39487 +:10774000AF14C8F304C0AF1410F4FA1801C0FF243A +:1077500084FE0EC080E390E0B60184D082FE1DC09E +:1077600081FE03C088E590E010C088E790E00DC07E +:10777000C40186789070009781F081FC02C080E29D +:1077800001C08BE2B7FC8DE290E0B6016BD005C082 +:1077900080E390E0B60166D0EA947E14C8F37A9450 +:1077A000F201E70DF11D808190E0B6015BD07720FA +:1077B000B1F705C080E290E0B60154D0FA94FF2002 +:1077C000C9F744CEF6012681378102C02FEF3FEF83 +:1077D000C9012C960FB6F894DEBF0FBECDBFCF9176 +:1077E000DF911F910F91FF90EF90DF90CF90BF90AE +:1077F000AF909F908F907F906F905F904F903F9051 +:107800002F900895F999FECF92BD81BDF89A9927DE +:1078100080B50895262FF999FECF92BD81BDF89AC3 +:10782000019700B4021639F01FBA20BD0FB6F894C4 +:10783000FA9AF99A0FBE0895FC01059061507040C4 +:107840000110D8F7809590958E0F9F1F0895FC0129 +:107850006150704001900110D8F7809590958E0F7F +:107860009F1F08950F931F93CF93DF938C01EB011C +:107870008B8181FF1BC082FF0DC02E813F818C81D7 +:107880009D812817390764F4E881F9810193F98310 +:10789000E88306C0E885F985802F0995009731F4C3 +:1078A0008E819F8101969F838E8302C00FEF1FEF11 +:1078B000C801DF91CF911F910F910895FA01AA2776 +:1078C000283051F1203181F1E8946F936E7F6E5F23 +:1078D0007F4F8F4F9F4FAF4FB1E03ED0B4E03CD0D1 +:1078E000670F781F891F9A1FA11D680F791F8A1FB4 +:1078F000911DA11D6A0F711D811D911DA11D20D01B +:1079000009F468943F912AE0269F11243019305DD4 +:107910003193DEF6CF010895462F4770405D4193C5 +:10792000B3E00FD0C9F7F6CF462F4F70405D4A3312 +:1079300018F0495D31FD4052419302D0A9F7EACFDA +:10794000B4E0A6959795879577956795BA95C9F709 +:1079500000976105710508959B01AC010A2E0694FC +:107960005795479537952795BA95C9F7620F731FB5 +:10797000841F951FA01D089517E000E0C4E6D7E01E +:1079800040E005C022974109FE014BBFB3DCC6367B +:0A799000D1074007B9F7F894FFCFC4 +:10799A002E2E0053656C656374204469736B006E08 +:1079AA006F20696D6167652066696C657320666F13 +:1079BA00756E640001030507090E10121416181CCF +:1079CA001E696E636F6D706C657465207772697479 +:1079DA00650062616420736563746F722025642098 +:1079EA00666F722074256400627566206C6F636B23 +:1079FA0065642025642F25643A25640063686563FD +:107A0A006B73756D206661696C75726520300063F1 +:107A1A006865636B73756D206661696C7572652044 +:107A2A003100636865636B73756D206661696C7597 +:107A3A007265203200636865636B73756D206661D9 +:107A4A00696C0043504C44204669726D77617265D7 +:107A5A00202564002564002575006669726D7761CA +:107A6A0072652E78766600534420726561642065DB +:107A7A0072726F72205200526573756C743A207379 +:107A8A0075636365737300526573756C743A206528 +:107A9A0072726F72202564005344207265616420FB +:107AAA007374617274206572726F7200534420722B +:107ABA00656164206572726F722044007772207764 +:107ACA00726F6E6720747261636B2025642F256460 +:107ADA000052657665727465642074726B20253075 +:107AEA00326420202000534420726561642065724C +:107AFA00726F722057005344207772697465537409 +:107B0A00617274206661696C0053442077726974EB +:107B1A0065206572726F72005344207772697465CA +:107B2A0053746F70206661696C00536176656420D6 +:107B3A0074726B202530326420696E20256C7520A2 +:107B4A00200053442063617264206572726F722050 +:107B5A0025643A256400253032640025642000D566 +:107B6A00AAAD0000000000000000000000008A0129 +:107B7A00AD01D8010D024E02A2301B311D35713400 +:107B8A0024319A309A3003313D316236083109374F +:107B9A001C361C361C36D035D035D035D332C830D9 +:087BAA00C830C234A830993242 +:020000021000EC +:08EFF800DDDDDDDD000100009C +:00000001FF diff --git a/source-1.0L-F11/AVR/Release/makedep.mk b/source-1.0L-F11/AVR/Release/makedep.mk new file mode 100755 index 0000000..c047754 --- /dev/null +++ b/source-1.0L-F11/AVR/Release/makedep.mk @@ -0,0 +1,26 @@ +################################################################################ +# Automatically-generated file. Do not edit or delete the file +################################################################################ + +diskmenu.cpp + +floppyemu.cpp + +millitimer.cpp + +noklcd.cpp + +SdFat\Sd2Card.cpp + +SdFat\SdBaseFile.cpp + +SdFat\SdFat.cpp + +SdFat\SdVolume.cpp + +xsvf\lenval.cpp + +xsvf\micro.cpp + +xsvf\ports.cpp + diff --git a/source-1.0L-F11/AVR/Release/merged.hex b/source-1.0L-F11/AVR/Release/merged.hex new file mode 100755 index 0000000..307ebb6 --- /dev/null +++ b/source-1.0L-F11/AVR/Release/merged.hex @@ -0,0 +1,1123 @@ +:020000040000FA +:20000000B2C30000DFC30000DDC30000DBC300000C941F0ED7C300000C94AB0A0C94F7092F +:20002000D1C30000CFC30000CDC30000CBC30000C9C30000C7C30000C5C30000C3C3000058 +:20004000C1C30000BFC300000C945A1DBBC30000B9C30000B7C30000B5C30000B3C3000021 +:20006000B1C30000AFC30000ADC30000ABC30000A9C30000A7C30000A5C30000A3C3000018 +:20008000A1C300009FC300009DC3000000000C001800240030003C004800540060006C001E +:2000A0007800840090009C00A800B400C000CB00D600E100EC00F70002010D011801230149 +:2000C0002E01390144014F015A01650170017A0184018E019801A201AC01B601C001CA0135 +:2000E000D401DE01E801F201FC0106021002190222022B0234023D0246024F025802610222 +:200100006A0273027C0285028E029702A002A802B002B802C002C802D002D802E002E80214 +:20012000F002F80200030803100318030C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0B0B0B0BAB +:200140000B0B0B0B0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0909090957 +:200160000909090909090909090909090808080808080808080808080808080896979A9B31 +:200180009D9E9FA6A7ABACADAEAFB2B3B4B5B6B7B9BABBBCBDBEBFCBCDCECFD3D6D7D9DA10 +:2001A000DBDCDDDEDFE5E6E7E9EAEBECEDEEEFF2F3F4F5F6F7F9FAFBFCFDFEFF0001FFFF2A +:2001C0000203FF040506FFFFFFFFFFFF0708FFFFFF090A0B0C0DFFFF0E0F10111213FF145B +:2001E00015161718191AFFFFFFFFFFFFFFFFFFFFFF1BFF1C1D1EFFFFFF1FFFFF2021FF2290 +:20020000232425262728FFFFFFFFFF292A2BFF2C2D2E2F303132FFFF333435363738FF39C5 +:200220003A3B3C3D3E3F00002110422063308440A550C660E770088129914AA16BB18CC160 +:20024000ADD1CEE1EFF13112100273325222B5529442F772D662399318837BB35AA3BDD383 +:200260009CC3FFF3DEE36224433420040114E664C774A44485546AA54BB528850995EEE5C3 +:20028000CFF5ACC58DD55336722611163006D776F6669556B4465BB77AA719973887DFF743 +:2002A000FEE79DD7BCC7C448E5588668A7784008611802282338CCC9EDD98EE9AFF948897B +:2002C00069990AA92BB9F55AD44AB77A966A711A500A333A122AFDDBDCCBBFFB9EEB799B83 +:2002E000588B3BBB1AABA66C877CE44CC55C222C033C600C411CAEED8FFDECCDCDDD2AAD43 +:200300000BBD688D499D977EB66ED55EF44E133E322E511E700E9FFFBEEFDDDFFCCF1BBF42 +:200320003AAF599F788F8891A981CAB1EBA10CD12DC14EF16FE18010A100C230E3200450B7 +:20034000254046706760B9839893FBA3DAB33DC31CD37FE35EF3B1029012F322D2323542A2 +:20036000145277625672EAB5CBA5A89589856EF54FE52CD50DC5E234C324A01481046674A2 +:20038000476424540544DBA7FAB79987B8975FE77EF71DC73CD7D326F2369106B016576662 +:2003A0007676154634564CD96DC90EF92FE9C899E9898AB9ABA94458654806782768C0185A +:2003C000E1088238A3287DCB5CDB3FEB1EFBF98BD89BBBAB9ABB754A545A376A167AF10AA2 +:2003E000D01AB32A923A2EFD0FED6CDD4DCDAABD8BADE89DC98D267C076C645C454CA23C22 +:20040000832CE01CC10C1FEF3EFF5DCF7CDF9BAFBABFD98FF89F176E367E554E745E932E61 +:20042000B23ED10EF01E202020202020202020202020202020202020202020002049646C06 +:200440006500205265616400577269746500547261636B20202020536964650031343430CD +:200460004B204469736B436F707920696D616765003830304B204469736B436F7079206916 +:200480006D616765003430304B204469736B436F707920696D61676500313434304B2072D4 +:2004A000617720696D616765003830304B2072617720696D616765003430304B2072617788 +:2004C00020696D61676500696D616765206E6F7420636F6E746967756F7573006572726F5D +:2004E00072206F70656E696E6720696D61676500505245563A2043616E63656C004E45588F +:20050000543A204C6F6164206669726D7761726500626567696E0052656C656173652062E8 +:200520007574746F6E7320746F0043504C44204649524D5741524520555044415445004345 +:200540006F6E74726173743A200053454C4543543A2053617665004E4558543A20446172DD +:200560006B657200505245563A204C69676874657200626567696E0052656C6561736520ED +:20058000627574746F6E7320746F00434F4E54524153542041444A5553544D454E5400417B +:2005A00070702056657273696F6E20312E30204C002020202020464C4F50505920454D55B9 +:2005C00020202020202000507265737320616E7920627574746F6E006669726D77617265CD +:2005E0002E78766600436F756C64206E6F74206F70656E005570646174696E6720666972A2 +:200600006D776172652E2E2E00464154414C204552524F522020202020202020202000578B +:2006200052495445204552524F5220202020202020202020000000000017000300031F0A56 +:200640001F0A1F050904120F171C000303000E11110E00050205040E041008000404040062 +:2006600010001804031E110F021F0019151215150A07041F1715091E151D1905031A150B6E +:2006800017150F000A00040C04040E1F0A0A0A1F0E040115030E15161E051E1F150A0E1191 +:2006A000111F110E1F15151F05050E151D1F041F111F1108100F1F041B1F10101F061F1FAF +:2006C0000E1F0E110E1F05020E191E1F0D16121509011F010F101F0718071F0C1F1B041BDA +:2006E000031C031915131F101002040810101F0406041010100003031A161C1F120C0C1220 +:20070000120C121F0C1A16041E050C2A1E1F021C001D0010201D1F0C12111F101E0E1E1E47 +:20072000021C0C120C3E120C0C123E1C0202141E0A021F120E101E0E180E1E1C1E120C1232 +:2007400006281E1A1F16041B11001F00111B04080C047C3C3E5E2B3D3F2F5B5D3B2C2A22D2 +:200760005C00451D491D11241FBECFEFD0E4DEBFCDBF13E0A0E0B1E0EAE9F9E700E00BBF47 +:2007800002C007900D92A831B107D9F717E3A8E1B3E001C01D92AD3DB107E1F717E000E029 +:2007A000C4E6D7E040E006C022974109FE014BBF0E947A39C236D1074007B1F70E941918FF +:2007C0000C94BC3C1DCC2F923F924F925F926F927F928F929F92AF92BF92CF92DF92EF92EB +:2007E000FF920F931F93DF93CF93CDB7DEB72D970FB6F894DEBF0FBECDBF8B014A013E0106 +:200800000894611C711CD301E4E2F1E02DE001900D922150E1F7BB244424AA2452E8552E6F +:2008200042E2E42EF12CE80EF91E3EE0C32ED12CCC0EDD1E22E8222E312C280C391CC7016F +:20084000B80140E250E00E94C92480329105A1F4D8011B968C911B9790E09C012F73307079 +:200860002F30310559F183FD23C0F8018081853E19F1882309F05AC0D4011C9280E02D960B +:200880000FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F9058 +:2008A0008F907F906F905F904F903F902F900895F8018081882301F3BB24C1CFBB2021F519 +:2008C0008C91982F907E903409F0B9CF9FE1A92EA8221D964C90F1011082A5E7B0E085E725 +:2008E000582EF301AD01480D591D81919801280F311DD9018C91DA018D93AD01EC15FD0532 +:20090000A1F7BB24B3949BCFD8018C91AA948A1599F61D968C911D97841571F6552009F457 +:200920008ECFB3EF5B0EA52DB0E0DBCF8E3221F2BB2081F031962BE090E001C08191392FA7 +:200940003795332737959695932B980F2150B1F7941531F0C801B4010E94092481E08FCF26 +:20096000FA2DF130B9F7452D50E043385105B4F79A0160E080E090E0880D991D280D391DE0 +:20098000D9012C91FC0120836F5F862F90E09C01240F351F233831057CF381E070CFEF92E8 +:2009A000FF920F931F93DF93CF93CDB7DEB7A9970FB6F894DEBF0FBECDBFFC01DB018C91E8 +:2009C0008E32A9F1838590E0887190708031910509F466C0009759F5848D958DA68DB78D53 +:2009E000803020E4920726E0A20720E0B20709F459C0803020E892072CE0A20720E0B2076D +:200A000009F454C0803020E8920726E1A20720E0B20709F449C081509044A640B0408F3FBC +:200A20002FE2920721E1A20720E0B20778F020E0822FA9960FB6F894DEBF0FBECDBFCF91A9 +:200A4000DF911F910F91FF90EF900895CF017E010894E11CF11CB7010E9409241E86198A68 +:200A60008E01025F1F4FC801B70141E00E94342A882371F0C80165E773E340E052E00E940B +:200A8000C924C8010E9433278091C733813081F08989882361F2C8010E94332720E0C8CF0B +:200AA00021E0C6CF23E0C4CF25E0C2CF24E0C0CF8091C833882361F78091B63390E0A0E0E8 +:200AC000B0E0BA2FA92F982F88272091B733820F911DA11DB11DB695A79597958795B695CF +:200AE000A79597958795803921E0920720E0A20720E0B207F1F0803223E0920720E0A207E5 +:200B000020E0B207A1F0803A25E0920720E0A20720E0B20709F0BCCF28E08989882309F48B +:200B200087CFC80129A70E94332729A581CF27E0F4CF26E0F2CF2F923F924F925F926F92B6 +:200B40007F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7C05F5C +:200B6000D0400FB6F894DEBF0FBECDBF7C011092190310921803829640E050E0BA010E9461 +:200B80004B2603E4C02ED12CCC0EDD1E13E6A12EB12CAC0EBD1EB4E26B2E712CC701B601B8 +:200BA000A50111DE8823E1F1809118039091190321E08734920708F0A7C1C601B501EFDEBB +:200BC000882E882359F38091180390911903869D8001879D100D969D100D11240B581C4FC7 +:200BE000C801B50146E150E00E94B339B8016A5E7F4FC6010E940924809118039091190343 +:200C0000869DF001879DF00D969DF00D1124EB58FC4F83A201969093190380931803BECFF6 +:200C20002091180330911903C751DF4F39832883C95ED040F70185A182508230A8F184E286 +:200C400090E0C751DF4FE881F981C95ED040E89F8001E99F100DF89F100D11240B581C4F60 +:200C6000C80160E071E046E150E00E94B339C801469660E071E04DE050E00E94B33982E0B2 +:200C8000F80183A3C751DF4F28813981C95ED0402F5F3F4FC751DF4F39832883C95ED04055 +:200CA0003093190320931803A8E92A2EA3E03A2E80E090E07E010894E11CF11CF7E1CF2EE9 +:200CC000D12CCC0EDD1EC751DF4FE881F981C95ED0408E179F0708F01EC1FC013196C351E8 +:200CE000DF4FF983E883CD5ED040C751DF4F28813981C95ED040E217F30708F026C1C10130 +:200D00008397F101B496C151DF4FF983E883CF5ED0405F01C351DF4F48805980CD5ED0409B +:200D2000CA51DF4F8883C65ED04091012D503040C551DF4F39832883CB5ED040C951DF4F80 +:200D400039822882C75ED040392EC701CA51DF4F6881C65ED040732D46E150E00E94B339DF +:200D600088240AC00E0D1F1DF801808190E00E947E39F80180838394F70101900020E9F747 +:200D80003197EE19FF09082D10E00E171F0750F3EDED8E2EEFEF9E2E8A0C9B1C682C292C53 +:200DA000C601B40146E150E00E94B33977240AC00C0D1D1DF801808190E00E947E39F8015E +:200DC00080837394F60101900020E9F73197EC19FD09072D10E00E171F0750F3C701B6017D +:200DE00046E150E00E94A539282F392FC951DF4FE881F981C75ED04080818150823008F47D +:200E000080C0F50180818150823008F477C0121613060CF055C0CE018D96CA51DF4F68816F +:200E2000C65ED040732D46E150E00E94B339CA51DF4F8881C65ED040932D662D722D46E15A +:200E400050E00E94B339862D922DBE01635D7F4F46E150E00E94B339CE018D96C551DF4FFA +:200E600068817981CB5ED0404DE050E00E94B33984010A5E1F4FC551DF4F88819981CB5E80 +:200E8000D040B8014DE050E00E94B339C801BE01635D7F4F4DE050E00E94B339C951DF4F55 +:200EA000E881F981C75ED0408081F5019081C951DF4FE881F981C75ED0409083F5018083A6 +:200EC0000894411C511C24E230E0A20EB31EC751DF4F88819981C95ED0404816590608F4BC +:200EE00034CFC151DF4F28803980CF5ED040C351DF4F88819981CD5ED040E5CE28513C4FBA +:200F000086CF285E33407DCFC751DF4F99838883C95ED0408FCEC051DF4F0FB6F894DEBF09 +:200F20000FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F9072 +:200F40005F904F903F902F900895C1018496C151DF4F99838883CF5ED040C3CF8F929F9234 +:200F6000AF92BF92CF92DF92EF92FF920F931F93CF93DF9380911A0390911B0320911C0396 +:200F800030911D032817390728F430931B0320931A03C90104968217930730F42450304085 +:200FA00030931B0320931A0380E060E00E949A1D81E06FE70E948B1DC3E1D0E081E060E48D +:200FC0000E948B1D2197D1F783E091E00E948F1EC3E1D0E081E060E40E948B1D2197D1F761 +:200FE00081E06FE70E948B1D20911803309119032115310509F464C140911A0350911B03CC +:20100000CA0105964817590708F033C14217530708F02FC164E270E0469F7001479FF00C56 +:20102000569FF00C112488E993E0E80EF91EEA0191E0C92ED12CBB24B39480911C039091D2 +:201040001D03C817D90709F0BB24AC2C80E06C2D0E949A1D04E510E007C060E081E00E94CC +:201060008B1D0150104049F0BB20B9F36FE781E00E948B1D01501040B9F781E06A2D0E947B +:201080009A1D870103521040902E812EC8016B2D43E50E94A61DF70180818150823008F499 +:2010A000BDC0BB2009F0A4C08601219640911A0350911B03CA010596C817D907E0F12091A9 +:2010C0001803309119032630310508F047C0EE24E39482E56E2D0E949A1D81E060E00E9466 +:2010E0008B1D81E060E00E948B1DE3947E2D763081F780911A0390911B039801280F391F88 +:2011000040911C0350911D034217530708F4E2C02150304030931D0320931C0304301105AD +:2011200009F02CCF009709F429CF019790931B0380931A0323CF20911803309119030894EF +:20114000C11CD11C64E270E0E60EF71EC217D30708F471CF2630310508F4B9CFE7E2F0E08E +:201160004E9FC0014F9F900D5E9F900D11248D539F4FB9010E94293988E0E82EE60E83ECFA +:2011800090E0B9010E942939CE2CC61AC8E0D0E0BB24B39482E56B2D0E949A1D81E060E0D0 +:2011A0000E948B1D4C2F9E01295F3F4F2C173D070CF484C060E00AC0E41650F066956068E3 +:2011C0004F5F842F90E0281739074CF04C15A0F766954F5F842F90E028173907BCF781E02C +:2011E0000E948B1DB39428967B2D763099F681CF84E393E0692D782D46E150E00E94B33979 +:20120000B8016A5E7F4F8EE193E04DE050E00E94B339F701808180934A0346CF89E46A2D40 +:201220000E949A1DBB2041F181E06FE70E948B1D81E063E40E948B1D81E06DE50E948B1D58 +:2012400081E06DE50E948B1D81E06DE50E948B1D81E06BE50E948B1D81E06BE50E948B1D9E +:2012600081E063E40E948B1D6FE781E00E948B1D18CF00E010E027CF81E060E00E948B1DE3 +:2012800081E06CE30E948B1D81E062E20E948B1D81E062E20E948B1D81E062E20E948B1D87 +:2012A00081E064E20E948B1D81E064E20E948B1D81E06CE30E948B1D60E0D7CF60E08FCFCE +:2012C00080E061E00E949A1D8FE091E060E044E50E94A61DDF91CF911F910F91FF90EF9038 +:2012E000DF90CF90BF90AF909F908F9008958130910559F0009721F48091A135882309F4DC +:2013000008958EE995E30C94332710929E351092A13508958FE781B9559A209A3A9A3D9AB9 +:201320003E9A3B9A239A5C9A599A5A9A5F9A5B9A179A589A409A419A289A429A45984698C7 +:20134000439A2B9AE3E7F0E0808181608083EDE6F0E0808182608083808181608083089561 +:201360001F93DF93CF93CDB7DEB72A970FB6F894DEBF0FBECDBFCE010196DC01EEEDF2E0D6 +:201380002AE001900D922150E1F7E0914C03F0E0F595E795F595E795F595E795F595E79522 +:2013A0001FB7F894E53008F0E4E0F0E0EE0FFF1FE80FF91F20813181220F331F40E050E0DA +:2013C00060E07DE281E391E00E945F3930935B0320935A031FBF82E086BB2A960FB6F8949C +:2013E000DEBF0FBECDBFCF91DF911F9108951F920F920FB60F920BB60F9211242F933F93F7 +:201400004F935F936F937F938F939F93AF93BF93CF93DF93EF93FF93489B2FC0E0914C0382 +:2014200080915503882309F03DC0F0E0E45DFE4F249130E0220F331F21153105A9F5379922 +:201440005DC080914C038F5F80934C0380914C03882309F064C04598429A4899FECF429856 +:20146000459A7EDFC0919435D0919535C330D10508F057C081E080935103FF91EF91DF91CB +:20148000CF91BF91AF919F918F917F916F915F914F913F912F910F900BBE0F900FBE0F9029 +:2014A0001F90189524E230E080E090E040E050E068E188589A4CFC01808180FF03C06831B2 +:2014C00059F1542F4F5F842F90E0821793070CF1561708F4B4CF862FE82FF0E0E858FA4C30 +:2014E000908191FF03C09081916090839081946090838F5F581780F7379BA3CF80914C03E3 +:20150000882309F4A3CF80914C03815080934C039DCF4831E9F2CDCF542F642FD3CF459A2B +:201520009BCF8FE593E061E371E046E150E00E94B339C851DC4FD0937735C09376351092ED +:20154000500381E0809351038093520310929535109294358FCF1F920F920FB60F920BB65A +:201560000F9211241F932F933F934F935F936F937F938F939F93AF93BF93CF93DF93EF9329 +:20158000FF9386B190E095958795817090914E03891791F090915803923009F46DC010923E +:2015A0004E0311E010935103C0919435D0919535C330D10508F047C086B1817011E0812724 +:2015C000909150038917C9F08093500380915003882349F58FE781B9469880916B008F777B +:2015E00080936B00C0919435D0919535C330D10508F045C081E080935103FF91EF91DF911A +:20160000CF91BF91AF919F918F917F916F915F914F913F912F911F910F900BBE0F900FBE96 +:201620000F901F90189511B8469A80916B00806880936B0080B180788093933510929535B4 +:2016400010929435D7CF8FE593E061E371E046E150E00E94B339C053D84FD0937735C0937C +:2016600076351092500310935103109352031092953510929435A0CF80934E0392CF8FE55C +:2016800093E061E371E046E150E00E94B339C854D44FD0937735C093763510925003109379 +:2016A0005103109352031092953510929435A2CF1F93E0B1E0688091943590919535843092 +:2016C000910588F48330910509F487C0DC01A153BD4F2C912E1709F404C1109295351092BC +:2016E00094351F910895F0E0EA5DFE4FE49132E08F3B930748F59C012370307022303105F0 +:2017000009F4BBC02330310509F449C12130310509F418C1EE0FEE0FE093963540919A358C +:2017200050E09A01220F232F221F330B20939B35440F551F422B40939A35019690939535FF +:20174000809394351F910895F2E08F3B9F0709F4C1C022E0803C920709F4CEC032E0813CEF +:20176000930709F4E2C1F2E0823C9F0709F0B5CF80919635982F990F990F90939635E82B88 +:2017800090919A35E917C9F08FE593E062E971E046E150E00E94B33980E490E09093773595 +:2017A000809376351092500381E080935103809352031092953510929435E0919735F0E062 +:2017C000E858FA4C80818260808380818160808380818B7F80832B9A80CFF0E0EA5DFE4F32 +:2017E0001491E0914C0380915503882309F082C0F0E0E45DFE4FE4911E1708F04DC1E091B6 +:201800004C03882309F074C0F0E0E45DFE4FE49180914E03E89F802D1124810F8093973594 +:2018200090E0DC01A858BA4C2C9122FDE0C0982F8827990F8B589C4F90939D3580939C3514 +:201840008C9184608C938C918D7F8C9380914C038093903580914E03809391351093923543 +:201860002B9810929A3510929935109298358091943590919535019661CF50919635452FA9 +:20188000407C4E2B2091983542278431910578F0E0919C35F0919D354193F0939D35E09348 +:2018A0009C3550919635809194359091953560919B352091993530E0260F311D240F311D92 +:2018C0002093993530939B35550F550F50939635019634CFEE0FEE0FE093963580EC92E0CE +:2018E0002DCF20915403222309F0F7CE019626CFE2E18ECFE2E180CF80919635982F990FD8 +:20190000990F90939635807C8E2B90919835891709F46AC08FE593E06CE671E046E150E0E6 +:201920000E94B3398EE390E090937735809376351092500381E0809351038093520381E025 +:2019400090E0FCCE50919635452F407C4E2B20919A3542278431910578F0E0919C35F09199 +:201960009D354193F0939D35E0939C3550919635809194359091953560919B352091983578 +:2019800030E0260F311D240F311D2093983530939B35550F550F509396350196CFCE4091A5 +:2019A00096354E2B2091993542278431910568F0E0919C35F0919D354193F0939D35E09327 +:2019C0009C35809194359091953550919B3520919A3530E0250F311D240F311D20939A35AB +:2019E00030939B350196AACE81EC92E0A7CE30914C0320914E038DB79EB70C970FB6F89452 +:201A00009EBF0FBE8DBFADB7BEB711968FE593E0EDB7FEB79283818386E190E013969C93C8 +:201A20008E93129788E591E015969C938E93149716963C93169717961C92179718962C93BA +:201A4000189719961C9219971A961C931A971B961C920E94C2398DE390E0909377358093FC +:201A600076351092500381E0809351038093520310929535109294358091973590E02DB78E +:201A80003EB7245F3F4F0FB6F8943EBF0FBE2DBFDC01A858BA4CCBCE20914C038DB79EB724 +:201AA0000A970FB6F8949EBF0FBE8DBFADB7BEB711968FE593E0EDB7FEB79283818386E17E +:201AC00090E013969C938E93129782E491E015969C938E93149716961C93169717961C9214 +:201AE000179718962C93189719961C920E94C2398CE390E0909377358093763510925003C1 +:201B000081E080935103809352031092953510929435809155032DB73EB7265F3F4F0FB6A4 +:201B2000F8943EBF0FBE2DBF6ACE80919635982F990F990F90939635807C8E2B90919935A6 +:201B4000891759F08FE593E06FE771E046E150E00E94B3398FE390E0E7CE82EC92E0EECDF7 +:201B60004091560350915703E2EEF2E02591349160E07FEF2627372791EA692F632770E09D +:201B8000660F771F6A5D7D4FFB0165917491322F2227262737279327E92FF0E0EE0FFF1F9E +:201BA000EA5DFD4F65917491322F222726273727EBEFE327F0E0EE0FFF1FEA5DFD4F6591EA +:201BC0007491322F222726273727B82FBB0FA0E0AB58BC4F80E090E0722F6627ED91E327E6 +:201BE000F0E0EE0FFF1FEA5DFD4F2591349126273727019662E08030960771F73093570396 +:201C00002093560342175307C9F08FE593E065EA71E046E150E00E94B33986E490E09093E3 +:201C20007735809376351092500381E08093510380935203109295351092943508951F92F0 +:201C40000F920FB60F920BB60F9211242F933F934F935F936F937F938F939F93AF93BF9382 +:201C6000EF93FF9390B180915003882309F456C0892F807890919335891709F44FC0809395 +:201C8000933590915503992309F46FC0882309F461C020B12F7080919635282B2093963535 +:201CA00080919435909195358230910509F45FC0009709F446C08130910509F46DC032E0DE +:201CC0008330930708F458C0A2E083309A0709F49AC0B2E084309B0709F530E08091560316 +:201CE00090915703822B932B90935703809356038091973535DFE0919735F0E0E858FA4C91 +:201D000080818260808380818160808380818B7F80832B9A1092953510929435FF91EF913E +:201D2000BF91AF919F918F917F916F915F914F913F912F910F900BBE0F900FBE0F901F9031 +:201D40001895213A59F781E090E09093953580939435E4CF80B190E082959295907F982731 +:201D6000807F982780939635D9CFA2DCD7CF2B3FE9F0213A79F6D2CF30919735F32FFF0F90 +:201D8000E0E0E80FF91FEE58FC4F208301969093953580939435C2CF213A09F0BBCF82E00F +:201DA00090E09093953580939435B8CF83E090E0909395358093943520915903209397353B +:201DC000822F90E0FC01E858FA4C308132FD26C0982F8827990F8B589C4F90939D358093A5 +:201DE0009C3580818460808380818D7F808380914C038093903580914E03809391352093F4 +:201E000092352B988BCF109256032093570384E092E0909395358093943580CF50914C03B8 +:201E200040914E032DB73EB72C5030400FB6F8943EBF0FBE2DBFEDB7FEB731962FE533E06D +:201E4000ADB7BEB712963C932E93119726E130E03383228328E531E0358324835683178268 +:201E600040871186938782870E94C23987E490E090937735809376351092500381E0809373 +:201E800051038093520310929535109294352DB73EB7245F3F4F0FB6F8943EBF0FBE2DBFBE +:201EA0003DCFF89490915003992341F48F7782B9459A079BFECF0799FECF459878940895A3 +:201EC0008AE082B9459A079BFECF0799FECF4598E091570381EAE827F0E0EE0FFF1FEA5D4E +:201EE000FD4F859194913091560320E082279327909357038093560381E182B9459A079BD7 +:201F0000FECF0799FECF45980895982F92959F7092B9459A079BFECF0799FECF4598482FB6 +:201F20004F70E0915703E827F0E0EE0FFF1FEA5DFD4F859194913091560320E082279327D2 +:201F4000909357038093560342B9459A079BFECF0799FECF459808952F923F924F925F9204 +:201F60006F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF9300D00F92EE +:201F8000CDB7DEB78983692EA2EDCA2EA2E0DA2E992422243324EE24FF2400E010E088C0CD +:201FA0001070C801880F991F2801440C452C441C55085194482A592AF6010191852D99270D +:201FC000820D931D800F911DAFEF4A225524D6011196AC906F010894C11CD11CA7014A0D73 +:201FE000511D9C0120703170232F3327420F531F3FEF232E312C2822392271802FEFE22E96 +:20200000F12CE422F522872C8E24042510E0A224BB24F501E07CF070F595E795F595E795A5 +:20202000F595E795F595E7959801207C30703595279535952795E22BF32B882D82958695A1 +:202040008695837090E0E82BF92BE458FE4F84914A835B8326DF0F73107004581E4FF801B9 +:2020600084911FDF809151034A815B81882309F0A9C00894C11CD11C8201070D111D407059 +:202080005170452F5527040F151FF501EF73F070E458FE4F849105DFE82DF0E0EF73F07067 +:2020A000E458FE4F8491FDDE9394F92DFE3A41F0292D243009F074CF9981C92ED62C70CFB9 +:2020C0001070C801880F991F5801AA0CAB2CAA1CBB08B194A82AB92AD6010C91200E311C10 +:2020E0008B2D9927280E391E1196CC90EC0CF11CC10180709170892F9927E80EF91E0A256C +:2021000010E0C224DD24F601E07CF070F595E795F595E795F595E795F595E795C801807C58 +:2021200090709595879595958795E82BF92BE458FE4F8491B6DEF801EF73F070E458FE4F66 +:202140008491AFDEF601EF73F070E458FE4F8491A8DEF101E07CF070F695E795F695E79544 +:20216000C501807C90700024880F991F001C880F991F001C892F902DE82BF92BC701807C33 +:202180009070929582958F7089279F708927E82BF92BE458FE4F849184DEF101EF73F070A8 +:2021A000E458FE4F84917DDEF701EF73F070E458FE4F849176DEF501EF73F070E458FE4F39 +:2021C00084916FDE0F900F900F90CF91DF911F910F91FF90EF90DF90CF90BF90AF909F9007 +:2021E0008F907F906F905F904F903F902F900895CF93DF9380E060E00E949A1D81EB95E00B +:2022000061E00E94271E8FE995E00E9486398195880F865D62E00E949A1D8FE995E060E0F0 +:202220000E94271E4DB75EB7485050400FB6F8945EBF0FBE4DBFEDB7FEB73196CFE5D3E0A8 +:20224000ADB7BEB71296DC93CE93119786E190E09383828383EB91E09583848380915E0323 +:20226000868317820E94C239FE0101900020E9F73197EC1BFD0B4DB75EB7485F5F4F0FB685 +:20228000F8945EBF0FBE4DBF8E2F8195880F865D63E00E949A1DCE0160E044E50E94A61D36 +:2022A0002B980E94531D95E028E04FEF53ED60E3415050406040E1F700C0000085B18227D3 +:2022C00085B9915091F70E94571DDF91CF910895CF92DF92EF92FF920F931F93DF93CF93C8 +:2022E00000D000D0CDB7DEB780E060E00E949A1D0E94D21E80E060E00E949A1D8BE895E0B9 +:2023000060E00E94271E80E062E00E949A1D88E795E060E00E94271E80E063E00E949A1D94 +:2023200082E795E060E00E94271E499BFECF4A9BFCCF4C9BFACF80E060E00E949A1D0E94EC +:20234000D21E80E062E00E949A1D84E695E060E00E94271E80E063E00E949A1D87E595E0AF +:2023600060E00E94271E80E064E00E949A1D8AE495E060E00E94271E8E010F5F1F4F84EC54 +:20238000E82E81E0F82EB4E0CB2ED12C16C08091C7358F3F29F08091C7358F5F8093C73542 +:2023A00080E061E20E948B1D6091C73580E00E948B1D80E060E20E948B1D80E060E00E946B +:2023C0009A1D8FE395E060E00E94271E8091C7352DB73EB7285030400FB6F8943EBF0FBE4F +:2023E0002DBFEDB7FEB73196ADB7BEB712961C930E931197D382C282F582E4828683178240 +:202400000E94C2392DB73EB7285F3F4F0FB6F8943EBF0FBE2DBFC80160E044E50E94A61D93 +:202420008FEF99E6A8E181509040A040E1F700C00000499B04C04A9B02C04C99FACF4A9B1B +:20244000A6CF49990BC08091C735813808F4A8CF8091C73581508093C735A2CF4C99A0CF6F +:202460006091C73581E090E00E940A3C0F900F900F900F90CF91DF911F910F91FF90EF900C +:20248000DF90CF9008951F930E94D21E80E060E00E949A1D84E393E060E044E50E94A61DEC +:2024A00080E061E00E949A1D8EE995E36EE173E043E00E94342A882309F48AC080914A031E +:2024C000833029F1863019F182E0809358038EE995E36BEB75E34FEB55E30E9456238823CA +:2024E000D1F487EC94E060E00E94271E8FEF93E2A4EF81509040A040E1F700C0000010E07A +:202500008EE995E30E943327812F1F91089581E080935803DCCF80E061E00E949A1D80914E +:202520004A03853009F4BFC0863008F05FC0833009F4A1C0843039F489EA94E060E00E9495 +:20254000271E80914A0391E0863008F490E0909375354F998CC0992309F45CC081E08093FB +:20256000540348E754E060E070E08EE995E30E944B268EE995E365E773E040E052E00E948D +:20258000C924E0917503F0E0EA58FC4F108210928B0380E062E00E949A1D86E793E060E02B +:2025A00044E50E94A61D80E064E00E949A1D8EE494E060E00E94271E80915403882379F502 +:2025C00011E08EE995E30E943327812F1F9108958EE995E36EE173E041E00E94342A8823C5 +:2025E00009F464C081E08093540371CF873009F452C0873008F447C0883009F0A4CF8CE59A +:2026000094E060E00E94271E81E08093550380914A0399CF44E254E060E070E0A6CF8DE4BD +:2026200060E00E949A1D81E060E00E948B1D81E068E70E948B1D81E06EE70E948B1D81E0BB +:2026400069E70E948B1D81E069E70E948B1D81E06EE70E948B1D81E068E70E948B1D11E0FA +:202660008EE995E30E943327812F1F91089581E08093540370CF88EB94E060E00E94271E5A +:2026800080914A0360CF85E894E060E00E94271E80914A0358CF81E794E060E00E94271E1D +:2026A00080914A0350CF89E994E0ABCF8CED94E060E00E94271E1ACF1F931FB7F894E091BB +:2026C0004C03F0E0EE0FFF1FE850F041808180934C030E948A0910924C0310924D0310923A +:2026E000510310924E0310924F03109250031092530382E0809358031092590310925403EB +:20270000109255031092520310925D0310925C031092773510927635109295351092943553 +:2027200080E090E0FC01E858FA4C1082019688319105C1F711B8469A28988FE798E3A1E03B +:2027400081509040A040E1F700C0000080B18F7780935E0346988FE781B9289A80916400F0 +:20276000877F8093640083E48093800089E1809381000E94B0090E94DE1E0E94D21E1FBF7B +:202780001F910895FF920F931F93CF93DF938C01F0905203C0917635D09177358DDF0E94BA +:2027A000D21E80E060E00E949A1DFF2009F43FC08FE196E061E00E94271E80E061E00E94C4 +:2027C0009A1DC80160E044E50E94A61D8DB79EB708970FB6F8949EBF0FBE8DBFEDB7FEB753 +:2027E00031960FE513E0ADB7BEB712961C930E93119786E190E09383828387EC91E09583C4 +:202800008483D783C6830E94C2398DB79EB708960FB6F8949EBF0FBE8DBF80E065E00E942C +:202820009A1DC80160E044E50E94A61DFFCF89E096E061E00E94271E80E061E00E949A1D7B +:20284000C80160E044E50E94A61DF0CF1F93CF93DF930E94D21E80E060E00E949A1D84EF9E +:2028600095E060E00E94271E4A9BFECF8FEF99E6A8E181509040A040E1F700C000008EE9F4 +:2028800095E36AEC71E041E00E94342A882331F562E00E949A1D85EE95E060E00E94271E7D +:2028A00080E063E00E949A1D88ED95E060E00E94271E80E065E00E949A1D87EC95E060E0E5 +:2028C0000E94271E499B04C04A9B02C04C99FACF0E94D21EDF91CF911F9108958EE995E376 +:2028E00065E773E040E052E00E94C92497FD4DC01092BA351092B93586E195E10E94C93816 +:202900001FB7F8940E947338EC011FBF8EE995E30E94332780E062E00E949A1D209761F14E +:20292000ADB7BEB718970FB6F894BEBF0FBEADBFEDB7FEB731968FE593E012969C938E9309 +:20294000119786E190E09383828387EF91E095838483D783C6830E94C2398DB79EB7089660 +:202960000FB6F8949EBF0FBE8DBF8FE593E060E044E50E94A61D9DCF8FE593E067EE71E0E2 +:2029800046E150E00E94B339F0CF87ED91E0FADEAFCF80E060E00E949A1D0E94D21E80E06D +:2029A00060E00E949A1D8AE295E060E00E94271E80E062E00E949A1D87E195E060E00E94BC +:2029C000271E80E063E00E949A1D81E195E060E00E94271E499BFECF4A9BFCCF4C9BFACFA7 +:2029E00080E062E00E949A1D8DEF94E060E00E94271E80E063E00E949A1D80EF94E060E0A6 +:202A00000E94271E8FEF99E6A8E181509040A040E1F700C00000499B04C04A9B02C04C99FC +:202A2000FACF4A9B02C00C94D21E10CF2091B9353091BA3582E02030380759F0F901EB58F1 +:202A4000FC4F80812F5F3F4F3093BA352093B93508958EE995E365E773E040E052E00E949C +:202A6000C92497FD0BC01092BA351092B93585B198E0892785B920E030E0E0CF87ED91E0A9 +:202A800081DEF1CF909155039923E1F4E82FF0E0E45DFE4FE491F0E0262F30E02E173F0763 +:202AA000B4F4AF014F5F5F4F55954795E0FD14C031972E173F0759F06417B0F0862F8F5F91 +:202AC000841B0895262F30E02131310514F080E00895862F8F5F0895E42FF0E031972E179C +:202AE0003F0751F780E00895842F860F0895FF920F931F938C01F22E0E945520882379F1A8 +:202B0000C80165E773E30E94AD1F882391F1E9ECF3E3BF2DBB0FA0E0AB58BC4F81918D938E +:202B200085E3E537F807D1F7C80165E773E30E94AD1F882311F1E5E7F3E3BF2DBB0FA0E0EC +:202B4000AF5DBA4F81918D9383E3E93CF807D1F7C8010E943D201F910F91FF90089588E030 +:202B600092E010DEC80165E773E30E94AD1F882371F68CE192E006DECACF8CE192E002DEEF +:202B8000DACF2F923F924F925F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93FB +:202BA000DF93CF93CDB7DEB760970FB6F894DEBF0FBECDBF982E792E862E809155038823B5 +:202BC00009F4B7C004E210E062E1462E512C80E090E020E0FF2458E1E52E46E1A42EB12C62 +:202BE0003CE2C32E32E0D32E1801122F88589A4CDC018C9180FF35C080919035881661F15F +:202C0000809190352DB73EB72A5030400FB6F8943EBF0FBE2DBFEDB7FEB731962FE533E0CD +:202C2000ADB7BEB712963C932E931197B382A282D582C48286821782808711860E94C23909 +:202C40004DB75EB7465F5F4F0FB6F8945EBF0FBE4DBF8FE593E096DD5E2D583109F466C030 +:202C6000F12E1F5F812F90E0821593050CF45AC0BE2DB83109F43EC080915403882361F417 +:202C800066C0EE2DF0E0E858FA4C80818E7F808380818B7F8083E394FE1498F7EDB7FEB70D +:202CA00038970FB6F894FEBF0FBEEDBF31960FE513E0ADB7BEB712961C930E93119786E130 +:202CC00090E09383828381E492E095838483868217820E94C239EDB7FEB738960FB6F894BD +:202CE000FEBF0FBEEDBF80E065E024D7C80160E044E52CD760960FB6F894DEBF0FBECDBF8C +:202D0000CF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F905F904F903F902F +:202D20002F900895183109F4A3CF60CFF12EE12E98CFE62FF0E0E45DFE4FE4914E2E5524DE +:202D40008201000F111F01151105A1F240CFABD6D6D66B877C878D879E87FE1408F461C158 +:202D6000482D50E05A8749871A01220C331CC101880F991F880F991F880F991F820D931D77 +:202D80009C0140E050E029833A834B835C830E2DF101E457FF4F859194919C0140E050E052 +:202DA0002D833E834F8358871E2DAF2C42C0809091352091580330E040E050E069817A81A2 +:202DC0008B819C810E940A396B017C018091BB359091BC35A091BD35B091BE35C80ED91EC5 +:202DE000EA1EFB1E282D30E0429EC001439E900D529E900D1124AA2797FDA095BA2FC80E13 +:202E0000D91EEA1EFB1EC00ED11CE11CF11C2F853889322F2227330F2B583C4F892D972DEC +:202E2000B701A6010E947520882371F10F5FA01688F1402F50E0588B4F87FA01E858FA4C79 +:202E4000808180FDF3CF80915503882309F0AFCFC090BB35D090BC35E090BD35F090BE3541 +:202E6000C00ED11CE11CF11C2091580330E040E050E06D817E818F8198850E940A39C60E4E +:202E8000D71EE81EF91EC3CF86E592E07BDC0F5FA01678F6E12EFA2C80915503882309F086 +:202EA0004FC0F101E457FF4F65917491A090BB35B090BC35C090BD35D090BE35AE0CB11C20 +:202EC000C11CD11C80E090E02091580330E040E050E00E940A39A60EB71EC81ED91E0F2D65 +:202EE00010E00F5F1F4F0E191109222717FD2095322F892D972DB601A5010E9410228823FC +:202F000059F487C0F801E858FA4C80818E7F808380818B7F8083E394FE14D0F10E2D10E00A +:202F2000B801762F6627770F6B587C4F892D972D0E949E21882331F789E792E023DCE2CF52 +:202F40008091913590E0489E5001499EB00C589EB00C1124CC24B7FCC094DC2C8091BB3569 +:202F60009091BC35A091BD35B091BE35A80EB91ECA1EDB1EAE0CB11CC11CD11CB101660F02 +:202F8000771F660F771F660F771F620D731D9ACF892D972D0E945122882309F43EC089E17E +:202FA00080935D0384D5ABD5ADB7BEB71C970FB6F894BEBF0FBEADBFEDB7FEB731960FE51E +:202FC00013E012961C930E93119726E130E0338322832AE932E03583248329853A85378341 +:202FE00026832B853C854D855E85621B730B840B950B60877187828793870E94C2394DB735 +:203000005EB7445F5F4F0FB6F8945EBF0FBE4DBF6ACE86E692E0B6DB7FCF88E892E0B2DB9F +:20302000BECF282D30E03A8729871901220C331C33CF2F923F924F925F926F927F928F92FD +:203040009F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7CD54D0400FB692 +:20306000F894DEBF0FBECDBF18D526DBC1D89AD678948FE79AE1A6E081509040A040E1F7FB +:2030800000C0000010D58FE79AE1A6E081509040A040E1F700C00000499B05C04A9903C0AC +:2030A0004C9901C015D989E189831C821C8E1BA21EA28E010F5F1F4FC80160E00E94B62A4B +:2030C000882309F49FC42FE5822E23E0922EEFD4499905C04A9903C04C9B01C05ADCC801A7 +:2030E0000E949B05C8010E94AE072224332480915203882309F078C0F894D0904C03C09004 +:203100004E0310925103789480915303882309F07EC080915103882351F74B9B04C0079971 +:203120006DC0F1010995499918C080911C0390911D03009771F3019790931D0380931C039F +:20314000C8010E94AE078FEF94E3ACE081509040A040E1F700C00000DCCF4A9B49C04C9937 +:20316000D8CF80914A03813009F4A3C2823009F438C2809168008860809368008091680039 +:20318000846080936800809168008460809368008091680081608093680010924C030ED64E +:2031A00001D671D9882309F4A2CF8091540391E0892790915503992309F4826082B9459A1E +:2031C000A7E8B3E11197F1F700C000004598B2E4BA95F1F700C04298E1E0E093530380919D +:2031E0005203882309F488CF8FE593E0CBDA84CF80911C0390911D0301969ECF89B180FF6E +:2032000090CF86B180FF8DCF31998DCF8ACFED2CFF242DB73EB7285030400FB6F8943EBF73 +:203220000FBE2DBFEDB7FEB73196ADB7BEB712969C928E92119786E1482E512C538242824B +:20324000B6EC6B2EB2E07B2E75826482F782E6820E94C2392DB73EB7285F3F4F0FB6F8945E +:203260003EBF0FBE2DBF88E164E064D4C40160E044E56CD4AC2CBB248DB79EB708970FB691 +:20328000F8949EBF0FBE8DBFEDB7FEB73196ADB7BEB712969C928E92119753824282ABEC65 +:2032A0004A2EA2E05A2E55824482B782A6820E94C2392DB73EB7285F3F4F0FB6F8943EBFB5 +:2032C0000FBE2DBF88E364E035D4C40160E044E53DD480914D038D1509F45CC160914D03E0 +:2032E000C8014FDCD0924D03C0924F0380E090E0FC01E858FA4C20812D7F208301968831F1 +:203300009105B1F780915103882309F0F0CE80915003882309F030C13D2D303598F7809140 +:203320005503882309F05BC1F701E45DFE4F249180915903821710F01092590386B14B991B +:2033400008C3881F8827881F8EAF2C9D902D112423969FAF2397A701440F551FCA01880F1B +:20336000991F880F991F880F991F840F951F28968FAF289729969FAF299730E02A9DC00190 +:203380002B9D900D3A9D900D11242C01662457FC6094762C27964CAE5DAE6EAE7FAE2797B6 +:2033A0000E2CEF2C000CEE1CFF08000CEE1CFF1CAA0CBB1CA294B29460EFB622BA24A62294 +:2033C000BA245E2C5A285FAE852D90E084589E4F44575F4FFA01659074902B967FAE6EAEC4 +:2033E0002B972D2D2F7321962FAF2197E22FF0E0E458FE4F34912C963FAF2C97FC01F4919E +:203400002D96FFAF2D972296DFAE22972E96CFAE2E972401F6B0F094FF1CFF24FF1C09F4CE +:2034200013C16EAC6F1461F080E464E083D3FF2009F42FC182E494E060E009D421E02EAFEB +:2034400080915D03813009F42AC180915503882309F4ABC0E0905903F8946E2C772458E71A +:20346000852E55E3952E860C971CD4018C9181FD8FC08C9182FD8CC08C9184608C9381E031 +:203480007894882309F441C080915503882309F0F7C02B966EAD7FAD2B9780915903A0904C +:2034A000BB35B090BC35C090BD35D090BE35A80EB11CC11CD11C27968CAD9DADAEADBFAD02 +:2034C0002797A80EB91ECA1EDB1E80E090E02091580330E040E050E00E940A39A60EB71E16 +:2034E000C81ED91EE0D280917535882309F4B7C0C801B601A5012E2DFADAD9D2D4018C9171 +:2035000082608C938C918B7F8C9380915903882301F5FF2059F085B1B8E08B2785B980911F +:203520005D03823018F0815080935D0320915C03275E20935C032D3708F08CC030E08091BD +:203540005A0390915B03821B930B909389008093880080915503882379F122E3F22E06C0A4 +:203560008EE40E94850FFA9409F4BCC0809151038823B1F34201BBCD80E464E0DBD288E45C +:2035800094E060E064D3809151038823E1F3BACE80E076CF80915503882309F4B3CE80918C +:2035A0004F038C1509F09ACEADCEE090590323963FAD2397E30E50CFB7E3EB2EF12C0AC067 +:2035C0008FEF0E94510F0894E108F108E114F10409F4EFC080915103882391F3CBCF22E126 +:2035E000A7CE80914B03815080934B03C80161E00E943C2A80914B03882389F0FF249F2D41 +:20360000ADE09A9FB00111246B587E4CC80141E00E945A2AF39480914B03F81680F3109258 +:203620001D0310921C03BED3C8010E949B05C8010E94AE078FEF99E6A8E181509040A040E6 +:20364000E1F700C0000053CDC80122966FAD229798DAE7CE10925C0320E030E070CF930151 +:20366000322F2227330F2B583C4FC801B601A5013CD5882309F041CF87ED91E083D83DCF19 +:2036800028969FAD289729968FAD2997692F782F04CF8CE394E060E0DAD22B9A1EAE109292 +:2036A0005D0380E065E046D286E294E060E0CFD2CCCEF0904B03AF2DBDE0AB9FC00111240F +:2036C0008B589E4C6EE173E04DE050E00E94B339F394F0924B03C8016EE173E041E00E940B +:2036E0005A2A9DCF9CE0F92E80915103882309F041CF0E94850FFA94B9F7EFEFFFEFF0935B +:203700005703E09356030E94600F0E94600F0E94600F80915103882309F02CCF8EEF0E942D +:20372000850F80915103882309F024CF22968FAD22970E94850F80915103882309F01ACF24 +:203740002E968FAD2E970E94850F80915103882309F010CF809159038F5F0E94850F8091E4 +:203760005103882309F006CF82E00E94850FF09056038091570390915103992309F0FACEAE +:203780000E94850F80915103882309F0F3CE8F2D0E94850FFF2408C08EE40E94850FF3941D +:2037A000FF2DF63109F4F1C0809151038823A1F3E1CE80915803823009F4E4C0F2E0FF2EF7 +:2037C000E090590380915103882309F0D3CE85ED0E94510F80915103882309F0CBCE8AEAE9 +:2037E0000E94510F80915103882309F0C3CE86E90E94510F80915103882309F0BBCE2C9668 +:203800008FAD2C970E94510F80915103882309F0B1CEE0915903F0E0E458FE4F84910E9442 +:20382000510F80915103882309F0A4CE2D968FAD2D970E94510F80915103882309F09ACE77 +:20384000EF2DF0E0E458FE4F84910E94510F80915103882309F08ECE2196EFAD2197EE2559 +:203860002FADE227EF25EF73F0E0E458FE4F84910E94510F80915103882309F07BCE8EEDB0 +:203880000E94510F80915103882309F073CE8AEA0E94510FEAE0FE2E80915103882309F067 +:2038A00069CE8FEF0E94510FFA94B1F780915103882309F05FCE85ED0E94510F809151030C +:2038C000882309F057CE8AEA0E94510F80915103882309F04FCE8DEA0E94510F80915103A5 +:2038E000882309F047CEE0915903F0E0E458FE4F84910E94510FC301982F8827990F8B580D +:203900009C4F0E94AC0F80915103882309F032CE8EED0E94510F80915103882309F02ACED8 +:203920008AEA0E94510F80915103882309F022CE8FEF0E94510F22968FAD2297609159039E +:20394000A1D8809359034B9B65CD2296DFAC229742014598429A10925303C8016D2D11D92A +:203960008FE79AE1A6E081509040A040E1F700C000000E945C13C8010E949B05C8010E9430 +:20398000AE07B5CBA2E2FA2E1BCFFF2480915103882309F0EFCD0E94850FF3942F2D2C30FF +:2039A000A9F78FEF9FEF90935703809356030E94600F0E94600F0E94600F8091510388232F +:2039C00009F0D8CD8BEF0E94850F6301DC2CCC24DD0CA5E7B3E0CA0EDB1EEE24FF240AC065 +:2039E0000E94850F0894E11CF11CF0E0EF16F2E0FF06B9F1F60181916F01909151039923EB +:203A000079F3B8CDADB7BEB71A970FB6F894BEBF0FBEADBFEDB7FEB731969FE5892E93E056 +:203A2000992E12969C928E92119786E190E09383828382EB92E09583848389818683178285 +:203A40008B81808711860E94C239EDB7FEB73A960FB6F894FEBF0FBEEDBFC4010E94C21333 +:203A600036CBF09056038091570390915103992309F080CD0E94850F80915103882309F04B +:203A800079CD8F2D0E94850F56CF81E090E00C94770980E090E00C94770914BC83E085BD73 +:203AA00081E085BB089581E080936E00089510926E0008951F920F920FB60F9211248F938D +:203AC0009F93AF93BF938091C3359091C435A091C535B091C6350196A11DB11D8093C33568 +:203AE0009093C435A093C535B093C635BF91AF919F918F910F900FBE0F901F9018952FB712 +:203B0000F8946091C3357091C4358091C5359091C6352FBF089590E59CBD1DBC882341F001 +:203B20005E9A2A986EBD0DB407FEFDCF2A9A08955E98F7CF1F93162F682F606880E0EBDF71 +:203B4000612F606480E0E7DF1F910895AF92BF92CF92DF92EF92FF920F931F93CF93DF9300 +:203B6000D62EC42EE82EF92EBB248FE7A82EF70101917F01002359F4DF91CF911F910F914D +:203B8000FF90EF90DF90CF90BF90AF900895BC1498F70D3609F183E0089F80011124E801D9 +:203BA000CB52DA4F09521A4FFE016491660FD1106A2581E0B0DFB394C017D10749F4BC142F +:203BC000B0F6DD20C1F16FE781E0A5DFB394CFCF2196BC1460F6E8CFDD2079F163E481E0CD +:203BE0009ADFB394BC1408F0C2CFDD2051F16BE781E091DFB394BC1408F0B9CFDD2029F19C +:203C000067E681E088DFB394BC1408F0B0CFDD20D1F06BE781E07FDFB394BC1408F0A7CFAD +:203C2000DD2069F067E481E076DFB394BC1408F09ECFDD2041F660E0C7CF6CE3D0CF68E36E +:203C4000F2CF64E0D5CF64E0E5CF68E1DACFCF92DF92EF92FF920F931F93CF93DF93D62EC1 +:203C60008C010F5F1F4F2FE7C22EF8013197E491EE2331F1ED3679F183E0E89FF0011124CF +:203C8000EF01CB52DA4F98EDE92E95E0F92EEE0EFF1EFE016491660FD1106C2581E03BDF47 +:203CA0002196CE15DF05A9F7DD2099F06FE781E032DF0F5F1F4FF8013197E491EE23D1F6AE +:203CC000DF91CF911F910F91FF90EF90DF90CF90089560E0ECCFDD2089F081E063E41BDF38 +:203CE00081E06BE718DF81E067E615DF81E06BE712DF81E067E40FDF6FE7D9CF81E06CE38C +:203D00000ADF81E064E007DF81E068E104DF81E064E001DF81E068E3FEDE60E0C8CFEF923D +:203D2000FF920F931F93CF93DF93E82EF92EF70101917F010023E1F00D3609F183E0089F48 +:203D400080011124E801CB52DA4F08521A4FFE016491606481E0DFDE2196C017D107B9F7CF +:203D600081E060E4D8DEF70101917F01002321F7DF91CF911F910F91FF90EF90089581E077 +:203D80006EE5C9DE81E062E4C6DE81E06CE4C3DE81E062E4C0DE81E06CE5BDDE81E060E455 +:203DA000BADEC5CFCF93DF93C8EFD1E081E060E0B2DE2197D9F7DF91CF9108958FEB8093E8 +:203DC000C73584E18093C83584E08093C935569A279A259A229A209A2A98289A8FE798E3A2 +:203DE000A1E081509040A040E1F700C0000028988FE798E3A1E081509040A040E1F700C0DE +:203E00000000289A8FE798E3A1E081509040A040E1F700C0000080E090E00E94023C813FE5 +:203E2000E1F080E090E061EF0E940A3C6091C73581E090E00E940A3C80E061E26CDE609125 +:203E4000C73580E068DE6091C83580E064DE80E060E261DE80E06CE05ECE81E090E00E9404 +:203E6000023C8093C735E8CFFC014181842F90E09C013595279520652CBD40FD06C081E067 +:203E8000463019F08DBD2C98089580E08DBD2C980895BF92CF92DF92EF92FF920F931F9364 +:203EA000CF93DF938C016B017A0129DEEB01BB24BA94BEBC0DB407FEFDCF8EB5F80182834D +:203EC0008F3FB1F41CDE6C1B7D0B81E06D32780780F381E1F80180832C9A80E0DF91CF9120 +:203EE0001F910F91FF90EF90DF90CF90BF9008958E3F19F08FE08083EFCFE114F104F1F0D9 +:203F00000894E108F1088FEF8EBDE114F10471F0F60180E090E03FEF0DB407FEFDCF2EB5A5 +:203F200021933EBD01968E159F05B0F30DB407FEFDCF8EB5F601EE0DFF1D80838FEF8EBDA2 +:203F40000DB407FEFDCF8EB58FEF8EBD0DB407FEFDCF8EB52C9A81E0C1CF0F931F93CF9381 +:203F6000DF93EC018B0180DFCE01B80140E052E090DFDF91CF911F910F910895FF920F93BE +:203F80001F93CF93DF93EB01BADD8B01FF24FA94FEBC0DB407FEFDCF8EB58F3F69F0AFDD99 +:203FA000601B710B6C177D0798F380E0DF91CF911F910F91FF90089581E0DF91CF911F91EB +:203FC0000F91FF900895DF92EF92FF920F931F93CF93DF93EC01D62E79018A0145DFCE0181 +:203FE0006CE271E0CBDF8D2D80648EBD0DB407FEFDCF28E130E0D801C701022E04C0B69504 +:20400000A795979587950A94D2F78EBD0DB407FEFDCF285030408FEF283F380761F7DD2077 +:20402000E9F08D2D883001F587E88EBD0DB407FEFDCF8D2D8C30D1F02FEF9FEF9EBD0DB4F4 +:2040400007FEFDCF8EB58A8387FD0AC0DF91CF911F910F91FF90EF90DF90089585E9E5CF95 +:204060002223A1F32150EACF8FEFDFCF8FEF8EBD0DB407FEFDCF8EB5DFCFCF93DF93EC0104 +:20408000F3DECE016CE020E030E0A9019CDF882339F083E088832C9A80E0DF91CF9108952A +:2040A0002C9A81E0DF91CF910895CF93DF93EC019A01AB018B81833039F069E0220F331FB0 +:2040C000441F551F6A95D1F7CE0162E17CDF882339F085E088832C9A80E0DF91CF910895FE +:2040E0002C9A81E0DF91CF910895CF92DF92EF92FF920F931F93CF93DF93EC017A018B012C +:2041000069018B81833039F0A9E0EE0CFF1C001F111FAA95D1F7CE0161E1A801970153DFD5 +:20412000882369F084E088832C9A80E0DF91CF911F910F91FF90EF90DF90CF900895CE017E +:20414000B60140E052E0A5DEF1CF8F929F92BF92CF92DF92EF92FF920F931F93DF93CF9364 +:204160000F92CDB7DEB74C01B62EFC0113821082C6DC8B01249A2C9A2698259A279A249A82 +:204180002C9A85E0F401818382E58CBD1DBC8AE09FEF9EBD0DB407FEFDCF8150D1F7C4012F +:2041A00060E020E030E0A9010EDF782FF40182838130C9F0A4DC601B710BF7E0613D7F079B +:2041C00070F381E0F40180832C9A80E00F90CF91DF911F910F91FF90EF90DF90CF90BF9013 +:2041E0009F908F900895C40168E02AEA31E040E050E07983E8DE798182FF1FC0F40173834B +:20420000CC24DD247601C40167E320E030E0A901DADEC40169E2A7019601D5DEF4018283B9 +:204220008823D9F06CDC601B710BF7E0613D7F0750F38AE0F4018083C7CF84E02FEF2EBD28 +:204240000DB407FEFDCF9EB5F40192838150B9F79A3A79F082E08083B7CF83818230B1F06F +:204260002C9AFB2DF73070F088E1F401808380E0ADCF82E0F4018383C12CD12CE12CB0E4A4 +:20428000FB2EC1CFF401B18281E0A0CFC4016AE320E030E0A90197DE882321F088E0F40113 +:2042A000808392CF8FEF8EBD0DB407FEFDCF8EB5807C803C19F483E0F401838383E09FEFE8 +:2042C0009EBD0DB407FEFDCF2EB58150C9F7C8CFFC016EBDA42FB52F80E090E00DB407FE71 +:2042E000FDCF2C912EBD0DB407FEFDCF11962C9111972EBD0296129622E08030920771F7CE +:204300000DB407FEFDCF8FEF8EBD0DB407FEFDCF8FEF8EBD0DB407FEFDCF8FEF8EBD0DB4CB +:2043200007FEFDCF8EB582838F71853029F083E180832C9A80E0089581E008950F931F931A +:20434000CF93DF93EC018B018FDDCE0168E572E015DE882349F485E188832C9A80E0DF9154 +:20436000CF911F910F910895CE016CEFA801B0DF882389F32C9A81E0DF91CF911F910F9120 +:204380000895CF92DF92EF92FF920F931F93CF93DF93EC017A018B0169018B81833039F02E +:2043A00089E0EE0CFF1C001F111F8A95D1F7CE0168E1A801970107DE882369F086E0888396 +:2043C0002C9A80E0DF91CF911F910F91FF90EF90DF90CF900895CE016EEFA60179DF882348 +:2043E00079F3CE0168E572E0C9DD882319F487E18883E6CFCE016DE020E030E0A901E3DDC7 +:20440000882319F086E18883DBCF8FEF8EBD0DB407FEFDCF8EB58823A9F72C9A81E0D2CF1B +:20442000AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC015A016B017801890167E3DD +:2044400020E030E0A901BFDDCE0167E1A8019701BADD882379F089E088832C9A80E0DF91F9 +:20446000CF911F910F91FF90EF90DF90CF90BF90AF9008958B81833039F099E0AA0CBB1C97 +:20448000CC1CDD1C9A95D1F7CE0169E1A60195019ADD882319F087E08883DFCF2C9A81E07C +:2044A000DECFCF93DF93EC01DFDCCE0168E572E065DD882359F08DEF8EBD0DB407FEFDCFD6 +:2044C000CE0168E572E05ADD882339F482E188832C9A80E0DF91CF9108952C9A81E0DF91C7 +:2044E000CF910895CF93DF93EC019C012C5F3F4F898D9A8D41E050E060E070E00E94042D57 +:204500008823D9F08D899E89AF89B88D0097A105B10579F48C819D81AE81BF818D8B9E8B32 +:20452000AF8BB88F89818068898381E0DF91CF91089581E0DF91CF91089580E0DF91CF9130 +:204540000895CF92DF92EF92FF921F93CF93DF93EC0189899A89AB89BC89803E2FEF920744 +:204560002FE1A20720E0B20748F080E0DF91CF911F91FF90EF90DF90CF900895CE01B2DFD8 +:20458000882399F30E94D82A882379F3E98DFA8DCC80DD80EE80FF808EEF9FEFAFEFBFEF3F +:2045A000C80ED91EEA1EFB1E058404C0CC0CDD1CEE1CFF1C0A94D2F786859785A089B189D9 +:2045C000C80ED91EEA1EFB1E81E08093D637C092D035D092D135E092D235F092D33580E04A +:2045E00092E0E4EDF5E3DF019C011D9221503040E1F7E98DFA8D84818230C0F011E006C0A0 +:204600001F5FE98DFA8D8481181780F4B701A601410F511D611D711D8091D4379091D53705 +:2046200024ED35E3AEDE882359F79FCF20E032E040E050E0058404C0220F331F441F551F53 +:204640000A94D2F789899A89AB89BC89820F931FA41FB51F898B9A8BAB8BBC8B81E086CFFF +:20466000CF93DF93EC018C859D85AE85BF8541E0662309F440E0BC01CD01DAD7882381F0B0 +:20468000288930E0220F331F22953295307F3227207F32272C523A4CC901DF91CF9108951D +:2046A00020E030E0C901DF91CF9108956F927F928F929F92AF92BF92CF92DF92EF92FF92D9 +:2046C0000F931F93DF93CF9300D000D0CDB7DEB76C014B013A01DC015596ED90FD900D9195 +:2046E0001C915897E114F10401051105F1F05E010894A11CB11C10C0D801C7010196A11DEC +:20470000B11D29813A814B815C8182179307A407B507F9F47C018D01F601818D928DB8014E +:20472000A7019501CAD7882339F780E00F900F900F900F90CF91DF911F910F91FF90EF90B5 +:20474000DF90CF90BF90AF909F908F907F906F900895D60159966D917C915A97FB01878936 +:20476000803109F44CC0283F8FEF38078FEF48078FE05807D0F2F60185899689A789B08D6D +:204780000297A109B109FB01058404C0880F991FAA1FBB1F0A94D2F7268537854089518970 +:2047A000820F931FA41FB51FF40180839183A283B383FB0186859785A089B1890197A109F0 +:2047C000B1092481820F911DA11DB11DA80197012250304040405040058404C0220F331FAC +:2047E000441F551F0A94D2F7820F931FA41FB51FF30180839183A283B38381E097CF283F0D +:20480000FFEF3F07F0E04F07F0E05F0708F0B3CF8CCFE82FF92F80E090E03EE209C0DB015F +:20482000A90FB11D2C939F5F8F5F31968B3061F020812032C9F3883091F7DB01A90FB11D23 +:204840003C939F5F2081EBCF690F711DFB01108208951F93FB012BE030E231932150E9F71F +:20486000A82FB92F30E017E09A2F8B2F2D91222351F4FA019083818381E0FB019081903265 +:2048800079F01F9108952F32A1F32E3261F082E597E0FC010196E491EE2351F02E17C9F77E +:2048A00080E01F9108951A30D9F338E01AE0DCCF1317B0F32132A0F32F3790F7FB01E30FEA +:2048C000F11D822F81568A3108F4205220833F5FCBCF0F931F93CF93DF93EC018B018B8191 +:2048E000882331F4FB018789803141F08032F1F180E0DF91CF911F910F91089582E08B83D9 +:204900001D8A1E8A1F8A188E808D918DA0E0B0E0880F991FAA1FBB1F880F991FAA1FBB1FDA +:20492000880F991FAA1FBB1F880F991FAA1FBB1F880F991FAA1FBB1F898B9A8BAB8BBC8BEB +:204940001A8F098F81E089831C821D821E821F82188619861A861B861C861D861E861F861F +:20496000188ADF91CF911F910F91089583E08B83F801428D538D648D758D4D8B5E8B6F8B11 +:20498000788F9E012F5E3F4FC80124D78823C1F6AFCF2F923F924F925F926F927F928F921B +:2049A0009F92AF92BF92CF92DF92EF92FF920F931F93CF93DF938C01362FE72F2A01DC0118 +:2049C00013962C911397222329F011968C91119780FD16C02FEF3FEFC901DF91CF911F9114 +:2049E0000F91FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F902F90089558 +:204A0000E801C988DA88EB88FC88488559856A857B854201AA24BB24D701C601841B950B9B +:204A2000A60BB70B88169906AA06BB0608F093C04114510409F4BEC0832E9E2E6201A4E081 +:204A40002A2E312C200E311E612CF2E07F2E60C0FF2009F07AC0411551056105710509F025 +:204A6000ABC0E8018D899E89AF89B88D8C839D83AE83BF8346855785608971894F0D511D32 +:204A8000611D711D0297A109B109058404C0880F991FAA1FBB1F0A94D2F7480F591F6A1F0F +:204AA0007B1FE301CA19DB09CC16DD0608F4E601E2E0C030DE0709F452C0CB01BA0140E0BC +:204AC000B7D5882309F486CF95012C523A4CC401B901AE010E949C39AE0160E070E0F801D6 +:204AE00080859185A285B385480F591F6A1F7B1FD80118964D935D936D937C931B97CC1A4C +:204B0000DD0A09F457C08C0E9D1E13962C911397EFEFAE2EE1E0BE2EA422B5222230B9F135 +:204B2000D8015996ED91FC915A97DB01CA0129E0B695A795979587952A95D1F7F480FA94A9 +:204B4000F822A114B10409F483CFE8018C819D81AE81BF818FCF2601441A550A69CF809174 +:204B6000D0359091D135A091D235B091D335481759076A077B0709F4A0CF8091D43790912D +:204B8000D5379401B2DA882309F0A6CF23CF39E076956795579547953A95D1F7E801E98DFF +:204BA000FA8D828D938DA48DB58D480F591F6A1F7B1F77CF920110CFD80114964D915D91D3 +:204BC0006D917C911797CF01910177D5882309F401CFE801E98DFA8D8C819D81AE81BF8176 +:204BE00049CFDF93CF930F92CDB7DEB7BE016F5F7F4F41E050E0CDDE8130910539F02FEF2A +:204C00003FEFC9010F90CF91DF910895298130E0C9010F90CF91DF910895EF92FF920F934C +:204C20001F93CF93DF93EC018B81823050F420E030E0C901DF91CF911F910F91FF90EF90F7 +:204C40000895E884F9840A851B85CE01CADF97FDEECF88859985AA85BB854F96A11DB11DCB +:204C600088879987AA87BB87D801C70115E0B695A795979587951A95D1F78F70282F30E050 +:204C8000220F331F22953295307F3227207F32272C523A4CCECF8F929F92AF92BF92CF922D +:204CA000DF92EF92FF920F931F93CF93DF93EC014A015B012B81222309F465C089899A896D +:204CC000AB89BC8984179507A607B70708F45BC0223009F452C081149104A104B10409F4C0 +:204CE0006AC0488559856A857B85E98DFA8D258530E0275F3F4FDB01CA010197A109B10982 +:204D0000022E04C0B695A795979587950A94D2F7850174010894E108F1080109110904C008 +:204D200016950795F794E7942A95D2F7E816F9060A071B07B0F58D899E89AF89B88D8C8300 +:204D40009D83AE83BF8384E0C82ED12CCC0EDD1E0FC04C815D816E817F81898D9A8D960157 +:204D6000ACD40894E108F10801091109882359F0E114F1040105110561F788869986AA8662 +:204D8000BB8681E001C080E0DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F9078 +:204DA0000895411551056105710529F2E81AF90A0A0B1B0BC8CF1C821D821E821F821886C0 +:204DC00019861A861B8681E0DFCF0F931F93CF93DF93EC018B81882349F0898187FD0EC083 +:204DE000E7D3DF91CF911F910F91089581E0888380E0DF91CF911F910F910895CE0161E0A3 +:204E00002FDC8C01009791F3FC018081853E71F38B818230F8F08D899E89AF89B88DF80161 +:204E2000938F828FB58BA48BE091CC35F091CD35309759F0B8016A5E7F4FC8014896099537 +:204E4000F801808D918D938B828B89818F778983AFD3C7CF89899A89AB89BC89848F958FEA +:204E6000A68FB78FD8CFCF93DF93EC01AEDF1B82DF91CF9108956F927F928F929F92AF9213 +:204E8000BF92CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB7DEB77C015A016B01B8 +:204EA000DC0113968C9113978130A1F080E00F900F900F900F90CF91DF911F910F91FF90D8 +:204EC000EF90DF90CF90BF90AF909F908F907F906F90089511968C91119781FFE7CFF70164 +:204EE00081899289A389B48984179507A607B707E8F20097A105B10529F1F70160847184CA +:204F000082849384C701B601A501C5DE882371F2A114B104C104D104B9F4D70155964D914C +:204F20005D916D917C91589759968D919C915A97A3D6882309F4BACFF701158A168A178ADC +:204F4000108E40C081E0B3CFD70114964D915D916D917C91179759968D919C915A979E01FF +:204F60002F5F3F4FAAD3882309F4A0CFD7015996ED91FC915A9749815A816B817C81878920 +:204F80008031C9F1483F8FEF58078FEF68078FE07807C0F4CF0170D6882309F487CFD701C7 +:204FA00014964D915D916D917C91179759968D919C915A970FEF1FEF2FEF3FE086D4882349 +:204FC00009F474CFF701A18AB28AC38AD48A818180688183C701F9DE882309F467CFB60165 +:204FE000A5016A147B048C049D0410F4B401A301C70151DE5CCF483FBFEF5B07B0E06B07C5 +:20500000B0E07B07F8F6C6CF1F93CF93DF93EC01142FE62FF0E0EE0FFF1FE295F295F07FD8 +:20502000FE27E07FFE27DF01AC52BA4C1B968C911B97817149F0842F827131F01B8280E074 +:20504000DF91CF911F9108958091D0359091D135A091D235B091D3358C879D87AE87BF87C3 +:20506000688BEC52FA4C84899589A0E0B0E0DC01992788278D8B9E8BAF8BB88F428D538DC1 +:2050800060E070E0482B592B6A2B7B2B4D8B5E8B6F8B788F838590E0887190700097F1F49F +:2050A000848D958DA68DB78D898B9A8BAB8BBC8B81E08B83812F8F7089831C821D821E8289 +:2050C0001F82188619861A861B8614FD17C015FD1EC081E0DF91CF911F9108958031910514 +:2050E00009F0ACCF9E012F5E3F4F898D9A8D72D3882309F4A3CF84E08B83DCCFCE0140E0DA +:2051000050E0BA01B8DE882311F780E099CF49895A896B897C89CE01BEDD92CF8F929F92C8 +:20512000AF92BF92CF92DF92EF92FF920F931F93CF93DF935C01EB01C42E952E822E898D0D +:205140009A8DD5015A969C938E935997CB0140E050E0BA01A0DDDD24E884F9840A851B85B5 +:2051600089899A89AB89BC89E816F9060A071B0708F040C0CE0151DDFC01009709F476C095 +:20518000D801C70115E0B695A795979587951A95D1F7182F1F708081882391F0853E81F0FC +:2051A0008C2D992DBF014BE050E00E948F39009799F687FC5BC0C501612F482D25DF57C041 +:2051C000DD20A9F42091D0353091D1354091D2355091D335D5011C962D933D934D935C9310 +:2051E0001F9750961C9350978081DD24D394882309F0B2CF86FE3AC081FE38C0DD2009F004 +:2052000043C08B81823091F1CE019BD9882371F1C4EDD5E310E07E01EC2FFF2D80E2DF019A +:205220001D928A95E9F7DE018C2D992DFC018BE001900D928150E1F7E091CC35F091CD352C +:20524000309761F1BE01625F7F4FCE0140960995888999892E853F859B8B8A8B998F888F80 +:205260003F8B2E8BA5D1882309F0A5CF80E0DF91CF911F910F91FF90EF90DF90CF90BF9072 +:20528000AF909F908F900895F5011089C50161E0E7D9EC01009709F0BECFE8CF81E298E2F0 +:2052A000998B888B80E098E09F878E8720E038E081E298E2D1CF2F923F924F925F926F92AA +:2052C0007F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7C4549C +:2052E000D0400FB6F894DEBF0FBECDBF2C013B018E010E5B1F4FD80111965C934E9325967D +:205300002FAF25971C861F861FA21AA66115710509F45FC0FC018381882309F05AC0CA0199 +:20532000DA012C912F3209F470C073013CE0832E912C8C0E9D1E64015E010894A11CB11C0A +:2053400027E2222E312C2C0E3D1EB501A80181DA882369F1D801ED91FC91119780818F32F5 +:2053600041F43196D8011196FC93EE9381918F32C9F3882309F46FC0C601B701A50121E015 +:20538000CDDE8823A1F0E614F70421F0C7011DDDF7011382C814D904C9F076016401D801AA +:2053A0008D919C91B501A80154DA882399F600E08AA5882321F0CE01879607DD1AA68F856C +:2053C000882341F0CE010C9600DD04C061017401E6CF00E0802FCC5BDF4F0FB6F894DEBF81 +:2053E0000FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F906E +:205400005F904F903F902F9008959A012F5F3F4FC901F80131832083D9014C912F5F3F4FEF +:205420004F32B1F3F30123812250223008F47DCF87E2E82EF12CEC0EFD1ED30159966D9131 +:205440007C915A97C70145DA882309F4B0CFF801808191816BCFC201B701A50125962FAD42 +:2054600025975CDE082FA4CFFB01242F6091CA357091CB35AF011FCF0F931F93CF93DF9386 +:20548000EC01662399F08C010E5D1F4F1093CB350093CA35C801E7DCBE016C5F7F4FC801C5 +:2054A00018DADF91CF911F910F9108958C010E5D1F4FF0CFDF92EF92FF920F931F93DF93CF +:2054C000CF93CDB7DEB76C970FB6F894DEBF0FBECDBFFB01D42E19821C8220812F3229F1B4 +:2054E00022E2E22EF12CE80EF91E8E010F5F1F4FC801B701AF0121E0DEDE8823F1F08C817C +:20550000823070F1D701F8018BE101900D928150E1F7DD2021F0F092CB35E092CA3521E060 +:20552000C8012C8FA0DC2C8D0CC021812223C1F6642FA2DF282F8C8102C08C8120E0882356 +:2055400089F4822F6C960FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF9008959A +:2055600020E0EDCF8E010F5F1F4FDACF0F931F93CF93DF938C010E94A520882331F480E00F +:20558000DF91CF911F910F910895E8012496CE01B80141E0CDD3882321F0C80161E06CDF51 +:2055A000EFCFCE01B80140E0C3D3882341F3F5CF8091D637882311F481E008954091D035AA +:2055C0005091D1356091D2357091D3358091D4379091D53724ED35E30E94C121882321F130 +:2055E0004091D7375091D8376091D9377091DA37411551056105710521F41092D63781E01C +:2056000008958091D4379091D53724ED35E30E94C121882359F01092D7371092D837109200 +:20562000D9371092DA37E9CF80E0089580E00895DF92EF92FF920F931F937B018C01D42E13 +:205640008091D0359091D135A091D235B091D3358E159F05A007B107F1F0AADF882339F4A4 +:2056600080E01F910F91FF90EF90DF9008958091D4379091D537B801A70124ED35E30E94EB +:205680007520882369F3E092D035F092D1350093D2351093D335DD2049F081E08093D63773 +:2056A0001F910F91FF90EF90DF90089581E01F910F91FF90EF90DF900895CF92DF92EF9262 +:2056C000FF920F931F93CF93DF93EC017A018B01690189859A85AB85BC850196A11DB11DF2 +:2056E00084179507A607B70730F0EF89E03169F0E03209F445C080E0DF91CF911F910F9172 +:20570000FF90EF90DF90CF9008959927872F762F652F2B893C894D895E89620F731F841F85 +:20572000951F2091D0353091D1354091D2355091D335621773078407950729F040E078DFCD +:205740008823C9F2EF89E03169F18FE790E0A0E0B0E0E822F9220A231B23F701EE0FFF1F67 +:20576000EE0FFF1FEC52FA4C80819181A281B381BF70F60180839183A283B38381E0BCCF9C +:20578000CB01BA0127E096958795779567952A95D1F72B893C894D895E89620F731F841FC9 +:2057A000951FBFCF8FEF90E0A0E0B0E0E822F9220A231B23F701EE0FFF1FEC52FA4C808181 +:2057C0009181A0E0B0E0F60180839183A283B38381E092CF4F925F926F927F928F929F9246 +:2057E000AF92BF92CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB7DEB78C014983F9 +:205800005A836B837C832901842F952FA62FB72FAC01BD01CC24DD2476015E010894A11CD7 +:20582000B11C612CE2E07E2E812C912CC801950144DF882309F447C0D401C301F8010584EA +:2058400004C0880F991FAA1FBB1F0A94D2F7C80ED91EEA1EFB1E49815A816B817C8187899F +:20586000803119F1483F8FEF58078FEF68078FE07807E0F2F201C082D182E282F38281E09A +:205880000F900F900F900F90CF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F90B4 +:2058A0007F906F905F904F900895483FFFEF5F07F0E06F07F0E07F07E8F6C8019501FDDEE0 +:2058C000882309F0B9CF80E0DBCF4F925F926F927F928F929F92AF92BF92CF92DF92EF9277 +:2058E000FF920F931F93CF93DF93EC016A017B0128013901423051056105710590F0898586 +:205900009A85AB85BC850196A11DB11D84179507A607B70730F08F89803109F456C0803284 +:2059200091F080E0DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F90A0 +:205940005F904F9008954A015B0117E0B694A794979487941A95D1F78B899C89AD89BE8946 +:20596000880E991EAA1EBB1EC501B40141E060DE8823B9F28F898031A9F18FE790E0A0E040 +:20598000B0E0C822D922EA22FB22F601EE0FFF1FEE0FFF1FEC52FA4C40825182628273824A +:2059A0008A89823078F18D819E81AF81B885880D991DAA1DBB1D8093D7379093D837A093AF +:2059C000D937B093DA3781E0ADCF852E962EA72EBB248B899C89AD89BE89880E991EAA1E90 +:2059E000BB1EC2CF8FEF90E0A0E0B0E0C822D922EA22FB22F601EE0FFF1FEC52FA4C5182C8 +:205A00004082CECF81E08ECF2F923F924F925F926F927F928F929F92AF92BF92CF92DF923D +:205A2000EF92FF920F931F93DF93CF93CDB7DEB767970FB6F894DEBF0FBECDBF1C014987E1 +:205A40005A876B877C873E872D87FC0181859285A385B4859C01AD012F5F3F4F4F4F5F4FC9 +:205A60002D833E834F835887ED85FE854080518062807380411451046104710409F4BEC0AA +:205A80000894411C511C611C711C1F860097A105B10509F454C0D301C201CC24DD247601EE +:205AA0008E010F5F1F4F4C8A5D8A6E8A7F8A2EC04C015D01C101B501A4019801FEDD8823E8 +:205AC00009F43DC089819A81AB81BC810097A105B10509F44EC0A50194012F5F3F4F4F4F4B +:205AE0005F4F2C8B3D8B4E8B5F8BDA01C9010894C11CD11CE11CF11CF1012185328543858A +:205B00005485C216D306E406F506C8F44D805E806F807884481659066A067B0648F682E076 +:205B2000882E912CA12CB12C8C8A9D8AAE8ABF8AC101B501A4019801C0DD882319F680E01D +:205B400067960FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF9077 +:205B60009F908F907F906F905F904F903F902F900895D501C4010196A11DB11D2C013D01A7 +:205B80002C893D894E895F89421A530A640A750A29853A854B855C85421653066406750671 +:205BA00009F0A5CF4C885D886E887F88C101B501A4010FEF1FEF2FEF3FE087DE882309F44F +:205BC000BECF481459046A047B0458F59501840107C0970186014C145D046E047F0408F591 +:205BE000680179010894C108D108E108F108C101B701A6016ADE882361F7A1CFF101408014 +:205C0000518062807380F1E0FF8729853A854B855C85213031054105510509F437CF1F869E +:205C200035CFAD85BE854D915D916D917C9113974115510561057105C1F4ED85FE85408276 +:205C4000518262827382FF85FF2369F00894411C511C611C711CD1014D925D926D927C927C +:205C6000139781E06DCF81E06BCFC101930182012CDE882311F763CFAF92BF92CF92DF9216 +:205C8000EF92FF920F931F93DF93CF9300D000D0CDB7DEB76C017A018B0182E090E0A0E04B +:205CA000B0E0F60180839183A283B3835E010894A11CB11CC601B801A7019501FEDC882323 +:205CC00039F1C601B801A70100E010E09801FDDD8823F1F0E980FA800B811C81F601878990 +:205CE000803159F088EFE8168FEFF8068FEF08078FE01807F8F281E00CC0F8EFEF16FFEFAD +:205D0000FF06F0E00F07F0E01F07A0F281E001C080E00F900F900F900F90CF91DF911F9192 +:205D20000F91FF90EF90DF90CF90BF90AF9008956F927F928F929F92AF92BF92DF92EF92D4 +:205D4000FF920F931F93CF93DF93EC01142F7093D5376093D4371F8A82E090E0A0E0B0E0C2 +:205D600088839983AA83BB831092D6371092D7371092D8371092D9371092DA378FEF9FEF10 +:205D8000DC018093D0359093D135A093D235B093D335442309F444C0453078F080E0DF914B +:205DA000CF911F910F91FF90EF90DF90BF90AF909F908F907F906F90089560E070E0CB01D3 +:205DC00040E036DC882351F3212F30E022953295307F3227207F32272C533A4CF901E2548F +:205DE000FE4F808190E08F7790700097B9F6F901E653FE4F80819181A281B381843691055F +:205E0000A105B10558F22A533E4FF901E080F18002811381E114F1040105110521F4BECF48 +:205E2000EE24FF248701C801B70140E001DC882309F4B4CF8091DF359091E035F2E080301F +:205E40009F0709F0ABCF2091E435222309F4A6CF8091E2359091E335009709F49FCF609154 +:205E6000E135662309F49ACF2A8B6C831D8670E080E090E041E050E008C0282F2F5F2D8704 +:205E800001968930910509F489CFD82E9A01082E02C0220F331F0A94E2F72617370769F759 +:205EA0006091EA357091EB356115710509F47FC080E090E06D837E838F8398878090E23570 +:205EC0009090E335AA24BB248E0C9F1CA01EB11E8B8A9C8AAD8ABE8A6090E5357090E6351C +:205EE000798E688E2091E43530E040E050E00E940A39680D791D8A1D9B1D6A8F7B8F8C8F0E +:205F00009D8F9301220F331F22953295307F3227207F322721503E4F232F3327269540E03B +:205F200050E0260F371F481F591F2E873F87488B598B8091E7359091E835009709F440C096 +:205F4000A0E0B0E0E21AF30A040B150BE80EF91E0A1F1B1F04C016950795F794E794DA941A +:205F6000D2F7E986FA860B871C8725EFE2162FE0F20620E0020720E0120758F185EFE81644 +:205F80008FEFF80680E0080780E0180730F18091003690910136A0910236B09103368A8FDB +:205FA0009B8FAC8FBD8F80E28F8B81E0F8CE6091F8357091F9358091FA359091FB357ACF66 +:205FC0008091F4359091F535A091F635B091F735B9CF8CE08F8B80E0E2CE80E18F8B81E079 +:205FE000DECECF93DF93DC01CD91DC9111971C161D06DCF41296E0E0F0E020E030E0A901BA +:20600000542F432F322F22276D9170E080E090E0262B372B482B592B3196EC17FD0781F7D3 +:20602000B901CA01DF91CF91089520E030E0A901F7CFCF93DF93FB01DC012D913C91B901FC +:206040006E5F7F4FEC01C60FD71FE60FF71FD9011196A40FB51F2115310599F02150304004 +:206060008A9192914115510519F06C91862396231197891781F320E030E0C901DF91CF9168 +:20608000089521E030E0C901DF91CF910895CF93DF93FB0120813181DC012D933C93A0816B +:2060A000B181109701F1BD01615070401296EA0FFB1FEA01CA0FDB1FA80FB91F80E09A9163 +:2060C000229130E0290F311D280F311D81E02F3F310509F008F480E02E93615070409FEFE8 +:2060E0006F3F790761F7DF91CF910895EF92FF920F931F93CF93DF938B01FC017183608313 +:206100006115710581F022E0E22EF12CE80EF91EC0E0D0E0C7018C0F9D1F0E94CE38219618 +:20612000C017D107B9F7DF91CF911F910F91FF90EF90089524E030E0FC013783268384E05D +:2061400090E0089521E0FC01208380E090E00895EF92FF920F931F93DF93CF930F92CDB7C5 +:20616000DEB77C018E010F5F1F4FC8010E94CE3889818823D1F7F7011782168280E090E0BB +:206180000F90CF91DF911F910F91FF90EF9008950F931F93DF93CF930F92CDB7DEB78C0126 +:2061A000CE010196FBD78981823070F085E090E0F8019783868325E030E0C9010F90CF91BC +:2061C000DF911F910F910895F8019181933141F0882369F481E0F801828720E030E0EDCF2B +:2061E000882359F481E0818720E030E0E6CF86E0F801828720E030E0E0CF8DE0F8018187E4 +:2062000020E030E0DACF0B96C9D780E090E00895CF93DF93EC016C897D898E559F4F66DF45 +:206220006C897D89CE018B539F4F60DF80E090E0DF91CF910895FC016489758981589F4F9D +:2062400055DF80E090E008950F931F93CF93DF938C01EC016696CE0164E070E047DFCE01A7 +:20626000C0DEF801648775878687978780E090E0DF91CF911F910F9108950F931F93CF9332 +:20628000DF938C01EC016696CE0164E070E02EDFCE01A7DEF801608B718B828B938B695F7F +:2062A0007F4F8F4F9F4F28E030E040E050E00E945F39F801358B248B2132310564F086E0F7 +:2062C00090E09783868326E030E0C901DF91CF911F910F91089520E030E0C901DF91CF91E4 +:2062E0001F910F910895BC0181E090E02BD780E090E060E070E026D780E090E061E070E063 +:2063000021C74F925F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93CF9333 +:20632000DF93EC01F62E662309F4A4C08881861709F4EEC06730C1F06E30C1F48D30B1F0A6 +:2063400005E010E0C801DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F90B8 +:206360006F905F904F900895863051F700E010E0A8E0AA2EFCE0CF2EEEE06E2E7FE0B72EFE +:2063800062E0E62E992493945AE0752E45E0D42E37E0832E23E0422E99E0592EF81691F2F3 +:2063A000873009F495C08830A8F4833009F453C0843008F03CC08130A1F1823008F454C010 +:2063C0008F2D893008F49EC081E090E08CDF58828881E4CF8B3059F08C3078F4893009F43A +:2063E00067C08A3008F47DC09F2D9B3089F081E090E079DFC8828881D1CF8D3009F452C08B +:206400008D3000F18E3009F075C09F2D9B30E9F480E090E068DFF8828881C0CF8F2D8130D8 +:2064200019F181E090E05FDFE8828881B7CF853009F444C0863090F081E090E054DF888250 +:206440008881ACCF8F2D8D3019F381E090E04BDFB8828881A3CF9F2D9430D1F281E090E05F +:2064600042DFD88288819ACF80E090E03CDF9882888194CF81E090E036DF00E010E080E0A8 +:2064800090E060E070E05ED680E090E061E070E059D60F5F1F4F0530110589F7188200E017 +:2064A00010E050CF81E090E01EDF6882888176CF80E090E018DF7882888170CF8F2D86304C +:2064C00009F4A6CF81E090E00EDFA882888166CF9F2D943009F49CCF81E090E004DFA8824E +:2064E000F5CF8F2D813009F493CF81E090E0FBDEE8829BCF8F3009F491CFF88205E010E023 +:2065000088814CCF80E090E0EEDE4882888146CF863049F08D3009F029CF81E090E0E3DEA4 +:206520008EE0888323CF81E090E0DDDE87E088831DCFCF92DF92EF92FF920F931F93CF936C +:20654000DF93EC018C010A5E1F4FC80161E070E0CDDDC88CC80161E070E0C8DDD88CC801F5 +:2065600064E070E0C3DDC8013CDD7B018C0188858C1521F0CE0108966C2DC3DEC801B70115 +:2065800023D688858D1521F0CE0108966D2DB9DE80E090E0DF91CF911F910F91FF90EF90A6 +:2065A000DF90CF9008950F931F93DF93CF930F92CDB7DEB78C01CE010196F0D5C80108966F +:2065C00069819FDE9C01009719F0F80197838683C9010F90CF91DF911F910F9108954F92F4 +:2065E0005F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93CF93DF935B014C +:206600006C01FA0138012115310509F481C080819181D90111969C938E93808191818C01AB +:206620000E5F1F4F020F131FA114B104C104D10409F45DC022E0422E512C480E591E4E0E06 +:206640005F1E0CC00115110519F0D8019E928D01A114B104C104D10409F449C0F201829016 +:206660002F01EE24FF2499240894A108B108C108D1086114710429F0A114B104C104D10451 +:2066800081F1C82DD0E0BE016170707082E090E059D580E090E060E070E054D501151105BE +:2066A00049F08ED590E00E2C02C0880F991F0A94E2F7982A80E090E061E070E043D5A1141C +:2066C000B104C104D10409F4BDCF0894E11CF11CF8E0EF16F10409F4B5CFD595C7958C2E69 +:2066E000C3CF81E090E061E070E02CD5CACFDF91CF911F910F91FF90EF90DF90CF90BF90C1 +:20670000AF909F908F907F906F905F904F9008958081918100E010E087CF2F923F924F92C7 +:206720005F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7E2 +:20674000DEB728970FB6F894DEBF0FBECDBF3C01962E29833A834B835C831E830D8317013E +:206760002601B886AF82A9A051E0C52ED12C681509F487C029813A814B815C8121153105DE +:206780004105510529F58D8D9E8DAF8DB8A10097A105B10509F097C020E030E0C90128968A +:2067A0000FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F90D9 +:2067C0008F907F906F905F904F903F902F900895BB24EE24FF24C301692D93DD69817A81D0 +:2067E0008B819C814D815E8191018601F8DE4114510461F0C201B1014F8158851ADC41E0A0 +:20680000E42EF12C009711F0EE24FF24C114D104E9F0D3018C918F5F8C93E114F10459F0C8 +:206820002D8D3E8D4F8D58A1211531054105510511F0BA1448F1C301682D63DD8D8D9E8D10 +:20684000AF8DB8A10097A105B10591F4E114F10409F4A2CFB3948B2D81508A1508F4BBCFDE +:20686000AA2019F0AB1408F439C022E030E096CFC30161E046DD6D8D7E8D8F8D98A1A4D420 +:20688000E5CFCC24DD2476CFC30166E03ADDC30164E037DD8D8D9E8DAF8DB8A1B595A79571 +:2068A00097958795B595A795979587952D8D3E8D4F8D58A1280F391F4A1F5B1F2D8F3E8F6D +:2068C0004F8F58A3BBCFC30161E01BDD6D8D7E8D8F8D98A179D420E030E060CF23E030E05F +:2068E0005DCF8F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC018C010A5E1F4F5D +:206900006C897D89C801F2DB00D000D00F92288939894A895B89ECE5EE2EF12CEC0EFD1E5C +:2069200079E3C72ED12CCC0EDD1E6FE7A62EB12CAC0EBD1E8C859D85AE85BF85EDB7FEB795 +:2069400081839283A383B4838B858583CE01089664E08A84E2DE9C010F900F900F900F9011 +:206960000F90009711F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF9059 +:206980008F9008958F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC018C010A5E9A +:2069A0001F4FC80162E070E0A1DBC8011ADB6B017C01695F7F4F8F4F9F4F28E030E040E051 +:2069C00050E07DD4213231058CF026E030E03F832E83C901DF91CF911F910F91FF90EF90B0 +:2069E000DF90CF90BF90AF908F900895C801B9017DDB00D000D00F928C859D85AE85BF85B9 +:206A0000EDB7FEB781839283A383B4831582CE0108966BE0A7019601EE24FF24CC24DD24F3 +:206A2000AA24BB24898479DE9C010F900F900F900F900F90009769F2CACF6F927F928F92CF +:206A4000AF92BF92CF92DF92EF92FF920F931F93DF93CF930F92CDB7DEB73C01CE0101963B +:206A60009DD383010A5E1F4F298130E040E050E0295F3F4F4F4F5F4FF3E05595479537957B +:206A80002795FA95D1F7C801B90130DB00D000D00F92298130E040E050E0F30184859585F3 +:206AA000A685B785EDB7FEB781839283A383B4831582C30108966BE0EE24FF24CC24DD2436 +:206AC000AA24BB24F301818428DE9C010F900F900F900F900F90009719F0F301978386839B +:206AE000C9010F90CF91DF911F910F91FF90EF90DF90CF90BF90AF908F907F906F900895D9 +:206B00002F923F924F925F926F927F928F92AF92BF92CF92DF92EF92FF920F931F93DF93A2 +:206B2000CF9300D0CDB7DEB79A8389831A012B013901C801B901DADAC114D10419F0C601AF +:206B4000B301D4DA00D000D00F928E899F89A88DB98DEDB7FEB781839283A383B4838A8DF2 +:206B6000858389819A8164E0A2019101D6DD0F900F900F900F900F900F900F90CF91DF9193 +:206B80001F910F91FF90EF90DF90CF90BF90AF908F907F906F905F904F903F902F90089515 +:206BA0008F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC0189818131D9F114E0AF +:206BC000812E00D000D00F92488959896A897B892C893D898E010A5E1F4FBCE5EB2EF12C64 +:206BE000EC0EFD1EA9E3CA2ED12CCC0EDD1EEDB7FEB711821282138214821582CE0108967B +:206C0000AA24BB247DDF9C010F900F900F900F900F90009711F09F838E83C901DF91CF914E +:206C20001F910F91FF90EF90DF90CF90BF90AF908F9008958A84C5CF8F92AF92BF92CF9228 +:206C4000DF92EF92FF920F931F93CF93DF93EC0189818E30A9F104E0802E00D000D00F9267 +:206C6000488959896A897B892C893D898E010A5E1F4FEDB7FEB71182128213821482158248 +:206C8000CE010896EE24FF24CC24DD24AA24BB2437DF9C010F900F900F900F900F9000974F +:206CA00011F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F90089590 +:206CC0008A84CBCF8F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC0100D000D0C0 +:206CE0000F92488959896A897B892C893D898C010A5E1F4FECE5EE2EF12CE80EF91E99E3D8 +:206D0000C92ED12CCC0EDD1E8FE7A82EB12CAC0EBD1E8C859D85AE85BF85EDB7FEB78183E5 +:206D20009283A383B4838B858583CE0108968A84E7DE9C010F900F900F900F900F9000973A +:206D400011F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F900895EF +:206D6000CF92DF92EF92FF920F931F93CF93DF938C016B017901B8018AD9E601288139812E +:206D8000F701A081B181AD014150504057FD38C0FD013296EE0DFF1D1196A00FB11F60E04A +:206DA00010E08291882329F1EC9001E00AC0762F660F7123B1F0E02A959587958823C1F0E9 +:206DC000000F90E080FFF8CF662389F721503040B601620F731FEB011A8162E071E071239C +:206DE00051F7702F7095E72295958795882341F7EC924150504011978FEF4F3F580789F644 +:206E0000DF91CF911F910F91FF90EF90DF90CF9008952F923F924F925F926F927F928F9242 +:206E20009F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB761970FB6F89421 +:206E4000DEBF0FBECDBF3C01B6E14B2E512C480E591EFC0164897589C20148D9C301089677 +:206E60009D838C83F301E45AFF4FFF83EE83C301C99699878887AFE72A2E312C260C371C4E +:206E800000D000D00F92F301208931894289538984859585A685B785EDB7FEB781839283B7 +:206EA000A383B483F3018385EDB7FEB785838C819D8164E08201EE80FF80C884D98451013E +:206EC000F30182842ADC9B838A830F900F900F900F900F90009709F087C0C3018B539F4F05 +:206EE0009D878C87FC0140815181141615060CF09DC0E0E0F0E060E000E010E0E60DF71D86 +:206F0000E953FF4F8081882351F090E09C0121703070020F131F959587958823B1F76F5F12 +:206F2000E62FF0E0E417F5074CF3CE01019636D1222717FD2095322F095F1F4F2F4F3F4F74 +:206F4000E3E03595279517950795EA95D1F71F870E879924C30188519F4F9B878A87F301AF +:206F6000EE55FF4FF98BE88B8981981608F043C08A859B856E857F85B9D8C2016A857B856D +:206F8000488959892C853D85EBDE00D000D00F92F301208931894289538984859585A68575 +:206FA000B785EDB7FEB781839283A383B483F3018385EDB7FEB785838C819D8164E0820177 +:206FC000EE80FF80C884D9845101F3018284A5DB0F900F900F900F900F90009739F4939449 +:206FE0008981981640F4C4CF8A819B81F301978386839B838A838A819B8161960FB6F8943A +:20700000DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F9093 +:207020006F905F904F903F902F90089500E010E07CCFCF93DF93EC01188219821A821B820E +:207040001C821D821F821E821B86188681E089878A87188A198A1A8A1B8A1D8A1C8A1C8674 +:207060001D861E861F86CE01089660E04AD98E839F83DF91CF910895CF93DF93EC012E8144 +:207080003F812115310519F48881882321F0C901DF91CF910895CE01019680D08A819B81DE +:2070A000AC81BD810196A11DB11D8A839B83AC83BD83E981E83150F084E090E09F838E83DE +:2070C00024E030E0C901DF91CF910895F0E0EE0FFF1FE851FD4F0190F081E02DCE01099579 +:2070E0002E813F81D4CF0F931F93DF93CF93CDB7DEB7CB50D1400FB6F894DEBF0FBECDBFCA +:207100008E010F5F1F4FC80194DF2F8138852115310569F0C901C55FDE4F0FB6F894DEBF8D +:207120000FBECDBFCF91DF911F910F9108958981882381F7C801A0DF2F81388521153105EB +:20714000B1F3E8CF8130910551F08230910561F0009721F46115710571F4429808956115C9 +:20716000710539F0439A08956115710531F0459A089543980895429A08954598089580E0A2 +:2071800090E060E070E0DEDF80E090E061E070E0D9CF9093DC378093DB370895CF93DF935D +:2071A000EC01E091DB37F091DC37309729F009958883DF91CF9108951882DF91CF910895CE +:2071C00081E0349B80E00895AF92BF92CF92DF92EF92FF920F931F935B016C0116161706A6 +:2071E0001806190674F4EE24FF248701C8DF0894E11CF11C011D111DEA14FB040C051D0564 +:20720000ACF31F910F91FF90EF90DF90CF90BF90AF900895629FD001739FF001829FE00D95 +:20722000F11D649FE00DF11D929FF00D839FF00D749FF00D659FF00D9927729FB00DE11D58 +:20724000F91F639FB00DE11DF91FBD01CF0111240895AA1BBB1B51E107C0AA1FBB1FA617ED +:20726000B70710F0A61BB70B881F991F5A95A9F780959095BC01CD010895A1E21A2EAA1BED +:20728000BB1BFD010DC0AA1FBB1FEE1FFF1FA217B307E407F50720F0A21BB30BE40BF50BAB +:2072A000661F771F881F991F1A9469F760957095809590959B01AC01BD01CF01089597FB0C +:2072C000092E05260ED057FD04D0D7DF0AD0001C38F450954095309521953F4F4F4F5F4F5F +:2072E0000895F6F790958095709561957F4F8F4F9F4F08950790F691E02D09949111089591 +:2073000081568A5108F4805285580895FC0105900020E9F7809590958E0F9F1F0895FB01B3 +:20732000DC0104C08D910190801921F441505040C8F7881B990B0895FB01DC0102C001905F +:207340000D9241505040D8F70895FB01DC014150504030F08D910190801919F40020B9F7C2 +:20736000881B990B0895FB01DC014150504048F001900D920020C9F701C01D924150504056 +:20738000E0F708950F931F93DF93CF93CDB7DEB72E970FB6F894DEBF0FBECDBF0D891E89EF +:2073A0008F89988D26E02C831A83098397FF02C080E090E801979E838D839E01255E3F4F09 +:2073C000CE010196698D7A8DA90119D04D815E8157FD0AC02F813885421753070CF49A0131 +:2073E000020F131FF80110822E960FB6F894DEBF0FBECDBFCF91DF911F910F9108952F9236 +:207400003F924F925F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF9329 +:20742000CF93CDB7DEB72C970FB6F894DEBF0FBECDBF6C011B018A01FC0117821682838181 +:2074400081FFC4C12E010894411C511CF6019381F10193FD859193FF81911F01882309F483 +:20746000B1C1853239F493FD859193FF81911F01853221F490E0B601F5D1E8CFEE24FF24A7 +:2074800020E02032B0F48B3269F08C3228F4803251F0833271F40BC08D3239F0803349F456 +:2074A00021602CC02260246029C0286027C0206125C027FD2CC0382F30533A3098F426FF86 +:2074C00008C08E2D880FE82EEE0CEE0CE80EE30E15C08F2D880FF82EFF0CFF0CF80EF30E36 +:2074E00020620CC08E3221F426FD6CC1206406C08C3611F4206802C0883649F4F10193FD41 +:20750000859193FF81911F01882309F0BACF982F9554933018F09052933028F40C5F1F4F4F +:20752000FFE3F9830DC0833631F0833771F0833509F05CC021C0F801808189830E5F1F4F9C +:20754000420171E0A72EB12C15C062E0662E712C600E711EF8018080918026FF03C06E2D13 +:2075600070E002C06FEF7FEFC4012C8770D15C0183012C852F7716C052E0652E712C600E96 +:20758000711EF8018080918026FF03C06E2D70E002C06FEF7FEFC4012C874ED15C012C854C +:2075A0002068830123FD1EC007C080E290E0B6012C8758D1FA942C858F2D90E0A816B906AD +:2075C000A0F310C0F40127FD859127FF81914F0190E0B6012C8746D12C85F110FA940894C4 +:2075E000A108B108A114B10469F7E9C0843611F0893641F527FF08C0F80160817181828149 +:2076000093810C5F1F4F09C0F80160817181882777FD8095982F0E5F1F4F4FE6B42EB22223 +:2076200097FF09C090958095709561957F4F8F4F9F4FF0E8BF2AA2012AE030E03FD1782EE8 +:20764000741844C0853731F43FEEB32EB2222AE030E025C099EFB92EB2228F36C1F0803768 +:2076600020F4883509F0AEC00DC0803721F0883709F0A8C002C020E1B22AB4FE0BC084E09D +:20768000B82A08C0B4FE09C0E6E0BE2A06C028E030E005C020E130E002C020E132E0B7FED9 +:2076A00008C0F80160817181828193810C5F1F4F07C0F8016081718180E090E00E5F1F4F08 +:2076C000A201FCD0782E7418FFE7BF22B6FE0BC02EEFB2227E1438F4B4FE07C0B2FC05C028 +:2076E0008FEEB82202C0A72C01C0AE2C8B2D90E0B4FE0DC0FE01E70DF11D2081203319F45A +:20770000E9EEBE2209C0A394B2FE06C004C086789070009709F0A3948B2C9924B3FC13C0BD +:20772000B0FE0EC0AF1428F4E72CEF0CEA18AF2C07C0E72C05C080E290E0B60193D0A39441 +:20774000AF14C8F304C0AF1410F4FA1801C0FF2484FE0EC080E390E0B60184D082FE1DC09F +:2077600081FE03C088E590E010C088E790E00DC0C40186789070009781F081FC02C080E202 +:2077800001C08BE2B7FC8DE290E0B6016BD005C080E390E0B60166D0EA947E14C8F37A94D9 +:2077A000F201E70DF11D808190E0B6015BD07720B1F705C080E290E0B60154D0FA94FF2023 +:2077C000C9F744CEF6012681378102C02FEF3FEFC9012C960FB6F894DEBF0FBECDBFCF9140 +:2077E000DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F9066 +:207800002F900895F999FECF92BD81BDF89A992780B50895262FF999FECF92BD81BDF89A29 +:20782000019700B4021639F01FBA20BD0FB6F894FA9AF99A0FBE0895FC0105906150704030 +:207840000110D8F7809590958E0F9F1F0895FC016150704001900110D8F7809590958E0F70 +:207860009F1F08950F931F93CF93DF938C01EB018B8181FF1BC082FF0DC02E813F818C81DB +:207880009D812817390764F4E881F9810193F983E88306C0E885F985802F0995009731F4DB +:2078A0008E819F8101969F838E8302C00FEF1FEFC801DF91CF911F910F910895FA01AA27AF +:2078C000283051F1203181F1E8946F936E7F6E5F7F4F8F4F9F4FAF4FB1E03ED0B4E03CD03C +:2078E000670F781F891F9A1FA11D680F791F8A1F911DA11D6A0F711D811D911DA11D20D037 +:2079000009F468943F912AE0269F11243019305D3193DEF6CF010895462F4770405D419322 +:20792000B3E00FD0C9F7F6CF462F4F70405D4A3318F0495D31FD4052419302D0A9F7EACF95 +:20794000B4E0A6959795879577956795BA95C9F700976105710508959B01AC010A2E0694CE +:207960005795479537952795BA95C9F7620F731F841F951FA01D089517E000E0C4E6D7E0BC +:2079800040E005C022974109FE014BBFB3DCC636D1074007B9F7F894FFCF2E2E0053656CC2 +:2079A000656374204469736B006E6F20696D6167652066696C657320666F756E640001036D +:2079C0000507090E10121416181C1E696E636F6D706C657465207772697465006261642024 +:2079E000736563746F7220256420666F722074256400627566206C6F636B65642025642F23 +:207A000025643A256400636865636B73756D206661696C757265203000636865636B737589 +:207A20006D206661696C757265203100636865636B73756D206661696C7572652032006370 +:207A40006865636B73756D206661696C0043504C44204669726D77617265202564002564C8 +:207A6000002575006669726D776172652E7876660053442072656164206572726F7220527E +:207A800000526573756C743A207375636365737300526573756C743A206572726F722025CC +:207AA000640053442072656164207374617274206572726F7200534420726561642065722D +:207AC000726F7220440077722077726F6E6720747261636B2025642F25640052657665721F +:207AE0007465642074726B20253032642020200053442072656164206572726F7220570059 +:207B000053442077726974655374617274206661696C005344207772697465206572726FFF +:207B20007200534420777269746553746F70206661696C0053617665642074726B202530B6 +:207B4000326420696E20256C7520200053442063617264206572726F722025643A2564002B +:207B6000253032640025642000D5AAAD0000000000000000000000008A01AD01D8010D0224 +:207B80004E02A2301B311D35713424319A309A3003313D316236083109371C361C361C36EE +:127BA000D035D035D035D332C830C830C234A830993236 +:020000040001F9 +:20EFF800DDDDDDDD0001000097C00000B2C00000B0C00000AEC00000ACC00000AAC0000007 +:20F01800A8C00000A6C00000A4C00000A2C00000A0C000009EC000009CC000009AC00000D0 +:20F0380098C0000096C0000094C0000092C0000090C000008EC000008CC000008AC0000030 +:20F0580088C0000086C0000084C0000082C0000080C000007EC000007CC000007AC0000090 +:20F0780078C0000076C0000074C0000072C0000070C000001E051E1F150A0E11111F110E87 +:20F098001F15151F05050E151D1F041F111F1108100F1F041B1F10101F061F1F0E1F0E11D0 +:20F0B8000E1F05020010001F0D16121509011F010F101F0718071F0C1F000000031C030091 +:20F0D8000A004552524F525A58464C41534858495358454D5054590046454D555142494E32 +:08F0F800584E4F5458464F5585 +:20F100004E4400464C415348494E475846454D555142494E5851515100464C4F50505958E5 +:20F12000454D5558424F4F544C4F41444552000011241FBECFEFD0E4DEBFCDBF11E0A0E087 +:20F14000B1E0E8EEFFEF01E00BBF02C007900D92AA30B107D9F712E0AAE0B1E001C01D92D8 +:20F16000A733B107E1F7DBD03DC74ACF249A259A279A2E9A089588EC3197319731970000EE +:20F180008A95D1F7089502D02C9801C02C9A8FEF98E087FD2D9A87FF2D98880F1E998395DC +:20F1A0002F9A2F989A95A9F70895FB018BBF83E080935700E8958091570080FDFCCF81E1B1 +:20F1C00080935700E89508950F921F928BBFFB01DA0190E80D901D9081E080935700E8952E +:20F1E00032969A95B9F7FB0185E080935700E8958091570080FDFCCF81E180935700E89527 +:20F200001F900F9008955E9808955E9A0895A1E0B0E0ECE0F9EFB8C68983B8DF2A98898129 +:20F22000B7DF2A9A2196E2E0CBC6A2E0B0E0EAE1F9EFAAC66A838983E6DF89818068E7DFBF +:20F240006A81862F8064E3DF2296E2E0B9C6CF93DF93DBDFC8EFD1E080E0D9DF2197E1F7D1 +:20F26000DF91CF910895EF92FF920F931F93CF93DF938C01CADF1FC023E0829FC0011124B8 +:20F280000F5F1F4FEC01C753D0412CECE22E2FEEF22EE80EF91ECE01AA2797FDA095BA2FB6 +:20F2A000ABBFFC018791880FB2DF2196CE15DF0591F780E0ACDFC801AA2797FDA095BA2F6A +:20F2C000ABBFFC0187918823B9F6CDB7DEB7E6E073C61F93209A229A569A48DF2A98289A7A +:20F2E00018EC49DF1150E9F7289818EC44DF1150E9F7289A18EC3FDF1150E9F784DF81E28E +:20F3000086DF8FEB84DF84E182DF80E280DF8CE07EDF80E060E089DF9ADF1F910895A2E00B +:20F32000B0E0E4E9F9EF29C65C9A599A5A9A8FE493EC0197F1F700C00000499956C04C99AD +:20F3400054C0239AC6DF89E191EF8DDF80E062E06CDF8DE091E0A0D280E091E0ACD38823A9 +:20F3600009F03AC083E091EF7EDFEE24FF2487016E010894C11CD11C88E0B82EC801B701F9 +:20F3800014DF87E391E06FEF70E040E051E023D687E391E060E071E0A601ECD489819A81AF +:20F3A000009729F0C801B70147E351E00DDF85B18B2585B980E091E0A0E0B0E0E80EF91EC3 +:20F3C0000A1F1B1F90E0E91690EFF90691E0090790E0190799F603C080EF90EF44DF499B85 +:20F3E000FECF4C9BFCCF4A9BFACF80E090E0FC0125913491AFEF2F3F3A0711F0FC010995AF +:20F4000068DF80E060E011DF8AED90EF2CDFFFCFDF92EF92FF920F931F93182F042FF52ED2 +:20F42000E62ED72E87FF08C087E740E050E0BA01EFDF8230E0F41F77A6DE812FA9DE8D2D8D +:20F44000A7DE8E2DA5DE8F2DA3DE802FA1DE103421F0183421F081E003C085E901C087E80A +:20F4600097DE1AE094DE87FF02C01150D9F71F910F91FF90EF90DF900895A5E0B0E0E2E4ED +:20F48000FAEF7CC573DE04E676DE0150E9F70AE07DDE0150E9F780E440E050E0BA01B8DF06 +:20F4A000813009F067C088E44AEA51E060E070E0AFDF8130D1F58E010F5F1F4F45E0C42E93 +:20F4C000D12CCC0EDD1E780162DEF70181937F01EC15FD05C9F78B81813009F04BC08C8184 +:20F4E0008A3A09F047C008C046DE0894E108F108E114F10429F43EC030E1E32E37E2F32E7D +:20F5000089EE40E050E060E070E482DF882361F73DC03DDEF80181938F01EC15FD05C9F7B4 +:20F52000898186FF25C09CE026C089EE40E050E0BA016EDF823020F492E029EEE22E03C004 +:20F5400091E081E4E82E00E117E208C09D8313DE015010409D810115110561F08E2D40E0F5 +:20F5600050E0BA019D8354DF9D81882379F717C094E001C090E090930A019D8307DE81E004 +:20F580009D81911180E02596E8E014C58AE740E050E0BA013DDF882309F4BBCFEBCF80E506 +:20F5A00040E052E060E070E09D8332DF9D81882309F7E1CFA1E0B0E0EFEDFAEFDDC46C01DB +:20F5C000590180910A0183FD07C0E9E0440F551F661F771FEA95D1F781E51ADF882391F5EC +:20F5E00050E4E52E5CE9F52ED2DD8F3F39F40894E108F108E114F104B9F724C08E3F11F5E3 +:20F60000EE24FF24EA18FB0882E092E0E80EF91EE01AF10AA114B10429F0B9DD0894A1087C +:20F62000B108F8CFB4DDF60181936F0101501040C9F7ADDD0894E108F108E114F104C9F72B +:20F6400080E001C081E08983A1DD89812196EAE0AFC4CF93DF93C0910B01D0910C0162504F +:20F660007040804090402E813F81488559852250304040405040621773078407950780F4B0 +:20F680002A8130E040E050E02ED49B01AC018A899B89AC89BD89280F391F4A1F5B1F03C02D +:20F6A00020E030E0A901B901CA01DF91CF910895CF93DF93EC01E0910B01F0910C01198237 +:20F6C00018826C817D818E819F81613071058105910551F126813781408551856217730724 +:20F6E0008407950708F5611571058105910539F42081233021F466857785808991896887AF +:20F7000079878A879B87611571058105910511F0A0DF04C066857785808991896C877D8769 +:20F720008E879F8780E001C081E0DF91CF910895A4E0B0E0EDE9FBEF25C4DC01CB01E091C8 +:20F740000B01F0910C0182309105A105B10508F452C0268137814085518582179307A40785 +:20F76000B50708F048C02081223021F0233009F042C01CC0492F5A2F6B2F77270285138547 +:20F7800024853585400F511F621F731F9C013070220F331FCE01019602E010E00BDF8823A7 +:20F7A00051F529813A8140E050E029C0AC01BD0127E076956795579547952A95D1F7028516 +:20F7C000138524853585400F511F621F731F9C012F773070220F331F220F331FCE0101960D +:20F7E00004E010E0E7DE882331F429813A814B815C815F7004C021E030E040E050E0B901E4 +:20F80000CA012496E4E0DAC3A0E0B0E0E9E0FCEFB1C3F82EE92E5A016B012EEF31E002E0B6 +:20F8200010E0C8DE882369F58F2CE4014E019E2CE401888199812AEA8535920721F58F2D2F +:20F840009E2DB601A50126E330E0B4DE882331F48881998121E486349207B9F08F2D9E2D5A +:20F86000B601A50122E530E002E010E0A3DE882371F481E02881398191E42634390741F4A9 +:20F8800004C083E005C082E003C080E001C081E0CDB7DEB7ECE08AC3A8E2B0E0E1E5FCEFD8 +:20F8A00065C37C0110920C0110920B01009709F4F8C0E3DD80FDF7C06E010894C11CD11C31 +:20F8C000C60140E050E0BA019FDF8130C9F4C60140E050E0BA012EEB31E000E110E06ADE55 +:20F8E000882309F0E2C08D81882309F4E0C089849A84AB84BC84C601B501A40185DF03C089 +:20F90000882499245401833009F4CFC0882309F0CEC06E010894C11CD11CC601B501A401C1 +:20F920002DE030E004E210E045DE882309F0BDC0D60119966D917C911A9780E090E0611508 +:20F9400071058105910521F4688D798D8A8D9B8D2C8130E040E050E0C6D26DA37EA38FA3BE +:20F9600098A7F6014180528066247724480C591C6A1C7B1CD7011A964D925D926D927C9250 +:20F980001D97E9811296EC93D60114964D915C911597D70115965C934E931497D6011696A9 +:20F9A0006D917C91179780E090E0611571058105910521F46C897D898E899F8904E0569598 +:20F9C00047950A95E1F74A01AA24BB24D60111960D911C91129720E030E0601B710B820BD6 +:20F9E000930B2DA13EA14FA158A5621B730B840B950B681979098A099B092E2F30E040E0DE +:20FA000050E090D22E5F3F4F4F4F5F4FD70116962D933D934D935C931997273FBFE03B0713 +:20FA2000B0E04B07B0E05B0708F441C0273FEFEF3E07E0E04E07E0E05E0710F482E001C00B +:20FA400083E0D7018C93833029F488A199A1AAA1BBA108C08DA19EA1AFA1B8A5840D951D4D +:20FA6000A61DB71DF70186879787A08BB18B480C591C6A1C7B1C2DA13EA14FA158A5420E95 +:20FA8000531E641E751ED70152964D925D926D927C92559711961C921197F0920C01E0925B +:20FAA0000B0180E005C082E003C081E001C087E0A896E0E177C2ACE3B0E0E0E6FDEF54C248 +:20FAC000C0900B01D0900C01C114D10409F446C1F60111829E012F5F3F4F388B2F877C0174 +:20FAE000FC01208101962032D1F32F3209F47C01198A1A8A1B8A1C8AF7018081813240F46E +:20FB0000CE010D96D5DD1D8E882309F4F7C029C190E2892E8DE0482E512C4C0E5D1EBDE1D1 +:20FB20006B2E712C6C0E7D1EA8E22A2E312C2C0E3D1EEF85F889DF01CF010B9601C08D9280 +:20FB4000A817B907E1F790E0992428E0D701A90DB11D8C9193948132C0F08F32B1F08E32F4 +:20FB600011F0921738F0283081F48E3271F498E02BE0ECCF382F31563A3108F48052DF017C +:20FB8000A90FB11D8C939F5FE1CF91E0813208F090E09387C2018CDD882309F086C0498D80 +:20FBA0005A8D6B8D7C8D2D853E852F703070F5E0220F331FFA95E1F7C30100E210E0FADC7E +:20FBC000882309F0D1C08D8D882309F4CFC088A583FD0BC0F301AF85B889E215F30509F4D2 +:20FBE0006EC091918D919817C1F3A0900B01B0900C010D851E850F5F1F4F09F4B7C0898D10 +:20FC00009A8DAB8DBC8D0097A105B10509F4AEC098012F7030702115310509F043C0019607 +:20FC2000A11DB11D898F9A8FAB8FBC8F6D897E898F89988D611571058105910541F4F50105 +:20FC4000848195810817190708F090C02BC0F501228130E021503040A801E4E05695479559 +:20FC6000EA95E1F72423352321153105D9F460DD623071058105910508F476C0F501268125 +:20FC8000378140855185621773078407950708F06DC06D8B7E8B8F8B988FDBDC698F7A8FD8 +:20FCA0008B8F9C8F1E870D877ACF833009F059C0EF85F8899385992309F45AC052C0EF8552 +:20FCC000F88983858823D1F488A584FF51C0E90CF11CF30184899589A0E0B0E0DC0199279C +:20FCE0008827228D338D40E050E0822B932BA42BB52B898B9A8BAB8BBC8B1BCF8D8D882317 +:20FD000079F188A584FD2CC0BE01635E7F4FFB0184899589A0E0B0E0DC0199278827228D5F +:20FD2000338D40E050E0822B932BA42BB52BF601868F978FA0A3B1A3FB01848D958DA68D6E +:20FD4000B78DF601828F938FA48FB58F168A178A108E118E81E0818380E003C086E001C091 +:20FD600083E0EC96E2E11CC181E0FBCF83E0A0CF84E0F7CFA0E0B0E0EFEBFEEFF7C03C010C +:20FD80007B014A01C0910B01D0910C01FA0111821082209709F4A0C0898180FF9FC08A8D9E +:20FDA0009B8DAC8DBD8D2E893F89488D598D821B930BA40BB50B9B0140E050E08217930795 +:20FDC000A407B50708F47C015301412C72E0572E7AC08E899F89A88DB98D9C01AD013170CB +:20FDE000407050702115310541055105C1F59C01AD0169E056954795379527956A95D1F72B +:20FE0000CA80CA94C222C1F40097A105B10529F46E8D7F8D88A199A105C06AA17BA18CA10E +:20FE20009DA186DC623071058105910508F451C06AA37BA38CA39DA36AA17BA18CA19DA1C5 +:20FE400008DC611571058105910509F442C06C0D711D811D911D6EA37FA388A799A72E890B +:20FE60003F893170C201821B930B67018E159F0508F46C016114710419F480E090E001C07B +:20FE8000C5014EA15FA168A579A5860193DB882301F5960140E050E08E899F89A88DB98D4B +:20FEA000820F931FA41FB51F8E8B9F8BA88FB98FAC0CBD1CEC18FD08F401808191818C0D6B +:20FEC0009D1D91838083E114F10409F082CF80E006C0198281E003C086E001C085E0CDB728 +:20FEE000DEB7E0E15FC0629FD001739FF001829FE00DF11D649FE00DF11D929FF00D839F4E +:20FF0000F00D749FF00D659FF00D9927729FB00DE11DF91F639FB00DE11DF91FBD01CF01CC +:20FF200011240895A1E21A2EAA1BBB1BFD010DC0AA1FBB1FEE1FFF1FA217B307E407F50796 +:20FF400020F0A21BB30BE40BF50B661F771F881F991F1A9469F760957095809590959B01CF +:20FF6000AC01BD01CF0108952F923F924F925F926F927F928F929F92AF92BF92CF92DF927D +:20FF8000EF92FF920F931F93CF93DF93CDB7DEB7CA1BDB0B0FB6F894DEBF0FBECDBF09945F +:20FFA0002A88398848885F846E847D848C849B84AA84B984C884DF80EE80FD800C811B81CF +:20FFC000AA81B981CE0FD11D0FB6F894DEBF0FBECDBFED010895DC0101C06D934150504060 +:12FFE000E0F70895F894FFCF66656D752E62696E00002D +:040000050001F00006 +:00000001FF diff --git a/source-1.0L-F11/AVR/SdFat/Sd2Card.cpp b/source-1.0L-F11/AVR/SdFat/Sd2Card.cpp new file mode 100755 index 0000000..51ed7ec --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/Sd2Card.cpp @@ -0,0 +1,665 @@ +/* Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino Sd2Card Library. If not, see + * . + */ + +#define SDCARD_CS_PORT PORTB +#define SDCARD_CS_DDR DDRB +#define SDCARD_CS_PIN 4 + +#define SDCARD_CLK_PORT B +#define SDCARD_CLK_DDR DDRB +#define SDCARD_CLK_PIN 7 + +#define SDCARD_MOSI_PORT B +#define SDCARD_MOSI_DDR DDRB +#define SDCARD_MOSI_PIN 5 + +#define SDCARD_MISO_PORT B +#define SDCARD_MISO_DDR DDRB +#define SDCARD_MISO_PIN 6 + + +#include +#include "..\millitimer.h" + +//------------------------------------------------------------------------------ +#ifndef SOFTWARE_SPI +// functions for hardware SPI +//------------------------------------------------------------------------------ +// make sure SPCR rate is in expected bits +#if (SPR0 != 0 || SPR1 != 1) +#error unexpected SPCR bits +#endif +/** + * Initialize hardware SPI + * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6] + */ +static void spiInit(uint8_t spiRate) { + // See avr processor documentation + SPCR = (1 << SPE) | (1 << MSTR) | (spiRate >> 1); + SPSR = spiRate & 1 || spiRate == 6 ? 0 : 1 << SPI2X; +} +//------------------------------------------------------------------------------ +/** SPI receive a byte */ +static uint8_t spiRec() { + SPDR = 0XFF; + while (!(SPSR & (1 << SPIF))); + return SPDR; +} +//------------------------------------------------------------------------------ +/** SPI read data - only one call so force inline */ +static inline __attribute__((always_inline)) + void spiRead(uint8_t* buf, uint16_t nbyte) { + if (nbyte-- == 0) return; + SPDR = 0XFF; + for (uint16_t i = 0; i < nbyte; i++) { + while (!(SPSR & (1 << SPIF))); + buf[i] = SPDR; + SPDR = 0XFF; + } + while (!(SPSR & (1 << SPIF))); + buf[nbyte] = SPDR; +} +//------------------------------------------------------------------------------ +/** SPI send a byte */ +static void spiSend(uint8_t b) { + SPDR = b; + while (!(SPSR & (1 << SPIF))); +} +//------------------------------------------------------------------------------ +/** SPI send block - only one call so force inline */ +static inline __attribute__((always_inline)) + void spiSendBlock(uint8_t token, const uint8_t* buf) { + SPDR = token; + for (uint16_t i = 0; i < 512; i += 2) { + while (!(SPSR & (1 << SPIF))); + SPDR = buf[i]; + while (!(SPSR & (1 << SPIF))); + SPDR = buf[i + 1]; + } + while (!(SPSR & (1 << SPIF))); +} +//------------------------------------------------------------------------------ +#else // SOFTWARE_SPI +//------------------------------------------------------------------------------ +/** nop to tune soft SPI timing */ +#define nop asm volatile ("nop\n\t") +//------------------------------------------------------------------------------ +/** Soft SPI receive byte */ +static uint8_t spiRec() { + uint8_t data = 0; + // no interrupts during byte receive - about 8 us + cli(); + // output pin high - like sending 0XFF + fastDigitalWrite(SPI_MOSI_PIN, HIGH); + + for (uint8_t i = 0; i < 8; i++) { + fastDigitalWrite(SPI_SCK_PIN, HIGH); + + // adjust so SCK is nice + nop; + nop; + + data <<= 1; + + if (fastDigitalRead(SPI_MISO_PIN)) data |= 1; + + fastDigitalWrite(SPI_SCK_PIN, LOW); + } + // enable interrupts + sei(); + return data; +} +//------------------------------------------------------------------------------ +/** Soft SPI read data */ +static void spiRead(uint8_t* buf, uint16_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) { + buf[i] = spiRec(); + } +} +//------------------------------------------------------------------------------ +/** Soft SPI send byte */ +static void spiSend(uint8_t data) { + // no interrupts during byte send - about 8 us + cli(); + for (uint8_t i = 0; i < 8; i++) { + fastDigitalWrite(SPI_SCK_PIN, LOW); + + fastDigitalWrite(SPI_MOSI_PIN, data & 0X80); + + data <<= 1; + + fastDigitalWrite(SPI_SCK_PIN, HIGH); + } + // hold SCK high for a few ns + nop; + nop; + nop; + nop; + + fastDigitalWrite(SPI_SCK_PIN, LOW); + // enable interrupts + sei(); +} +//------------------------------------------------------------------------------ +/** Soft SPI send block */ + void spiSendBlock(uint8_t token, const uint8_t* buf) { + spiSend(token); + for (uint16_t i = 0; i < 512; i++) { + spiSend(buf[i]); + } +} +#endif // SOFTWARE_SPI +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { + // select card + chipSelectLow(); + + // wait up to 300 ms if busy + waitNotBusy(300); + + // send command + spiSend(cmd | 0x40); + + // send argument + for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); + + // send CRC + uint8_t crc = 0XFF; + if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 + if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA + spiSend(crc); + + // skip stuff byte for stop read + if (cmd == CMD12) spiRec(); + + // wait for response + for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++); + return status_; +} +//------------------------------------------------------------------------------ +/** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ +uint32_t Sd2Card::cardSize() { + csd_t csd; + if (!readCSD(&csd)) return 0; + if (csd.v1.csd_ver == 0) { + uint8_t read_bl_len = csd.v1.read_bl_len; + uint16_t c_size = (csd.v1.c_size_high << 10) + | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; + uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) + | csd.v1.c_size_mult_low; + return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); + } else if (csd.v2.csd_ver == 1) { + uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) + | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; + return (c_size + 1) << 10; + } else { + error(SD_CARD_ERROR_BAD_CSD); + return 0; + } +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectHigh() { + SDCARD_CS_PORT |= (1< SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_CMD0); + goto fail; + } + } + // check SD version + if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { + type(SD_CARD_TYPE_SD1); + } else { + // only need last byte of r7 response + for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); + if (status_ != 0XAA) { + error(SD_CARD_ERROR_CMD8); + goto fail; + } + type(SD_CARD_TYPE_SD2); + } + // initialize card and send host supports SDHC if SD2 + arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0; + + while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { + // check for timeout + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_ACMD41); + goto fail; + } + } + // if SD2 read OCR register to check for SDHC card + if (type() == SD_CARD_TYPE_SD2) { + if (cardCommand(CMD58, 0)) { + error(SD_CARD_ERROR_CMD58); + goto fail; + } + if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC); + // discard rest of ocr - contains allowed voltage range + for (uint8_t i = 0; i < 3; i++) spiRec(); + } + chipSelectHigh(); + +#ifndef SOFTWARE_SPI + return setSckRate(sckRateID); +#else // SOFTWARE_SPI + return true; +#endif // SOFTWARE_SPI + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Read a 512 byte block from an SD card. + * + * \param[in] blockNumber Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { + // use address if not SDHC card + if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD17, blockNumber)) { + error(SD_CARD_ERROR_CMD17); + goto fail; + } + return readData(dst, 512); + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Read one data block in a multiple block read sequence + * + * \param[in] dst Pointer to the location for the data to be read. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readData(uint8_t *dst) { + chipSelectLow(); + return readData(dst, 512); +} +//------------------------------------------------------------------------------ +bool Sd2Card::readData(uint8_t* dst, uint16_t count) { + // wait for start block token + uint16_t t0 = millis(); + while ((status_ = spiRec()) == 0XFF) { + if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + } + if (status_ != DATA_START_BLOCK) { + error(SD_CARD_ERROR_READ); + goto fail; + } + // transfer data + spiRead(dst, count); + + // discard CRC + spiRec(); + spiRec(); + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +bool Sd2Card::readRegister(uint8_t cmd, void* buf) { + uint8_t* dst = reinterpret_cast(buf); + if (cardCommand(cmd, 0)) { + error(SD_CARD_ERROR_READ_REG); + goto fail; + } + return readData(dst, 16); + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a read multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStart(uint32_t blockNumber) { + if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD18, blockNumber)) { + error(SD_CARD_ERROR_CMD18); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a read multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStop() { + chipSelectLow(); + if (cardCommand(CMD12, 0)) { + error(SD_CARD_ERROR_CMD12); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Set the SPI clock rate. + * + * \param[in] sckRateID A value in the range [0, 6]. + * + * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum + * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 + * for \a scsRateID = 6. + * + * \return The value one, true, is returned for success and the value zero, + * false, is returned for an invalid value of \a sckRateID. + */ +bool Sd2Card::setSckRate(uint8_t sckRateID) { + if (sckRateID > 6) { + error(SD_CARD_ERROR_SCK_RATE); + return false; + } + spiRate_ = sckRateID; + return true; +} +//------------------------------------------------------------------------------ +// wait for card to go not busy +bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) { + uint16_t t0 = millis(); + while (spiRec() != 0XFF) { + if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** + * Writes a 512 byte block to an SD card. + * + * \param[in] blockNumber Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD24, blockNumber)) { + error(SD_CARD_ERROR_CMD24); + goto fail; + } + if (!writeData(DATA_START_BLOCK, src)) goto fail; + + // wait for flash programming to complete + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } + + // response is r2 so get and check two bytes for nonzero + if (cardCommand(CMD13, 0) || spiRec()) { + error(SD_CARD_ERROR_WRITE_PROGRAMMING); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Write one data block in a multiple block write sequence + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeData(const uint8_t* src) { + chipSelectLow(); + // wait for previous write to finish + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail; + chipSelectHigh(); + return true; + + fail: + error(SD_CARD_ERROR_WRITE_MULTIPLE); + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { + spiSendBlock(token, src); + + spiSend(0xff); // dummy crc + spiSend(0xff); // dummy crc + + status_ = spiRec(); + if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { + error(SD_CARD_ERROR_WRITE); + goto fail; + } + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { + // send pre-erase count + if (cardAcmd(ACMD23, eraseCount)) { + error(SD_CARD_ERROR_ACMD23); + goto fail; + } + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD25, blockNumber)) { + error(SD_CARD_ERROR_CMD25); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a write multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStop() { + chipSelectLow(); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + spiSend(STOP_TRAN_TOKEN); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + chipSelectHigh(); + return true; + + fail: + error(SD_CARD_ERROR_STOP_TRAN); + chipSelectHigh(); + return false; +} diff --git a/source-1.0L-F11/AVR/SdFat/Sd2Card.h b/source-1.0L-F11/AVR/SdFat/Sd2Card.h new file mode 100755 index 0000000..2ceb0cb --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/Sd2Card.h @@ -0,0 +1,207 @@ +/* Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino Sd2Card Library. If not, see + * . + */ +#ifndef Sd2Card_h +#define Sd2Card_h +/** + * \file + * \brief Sd2Card class for V2 SD/SDHC cards + */ +#include +//#include +#include +//------------------------------------------------------------------------------ +// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6 +/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ +uint8_t const SPI_FULL_SPEED = 0; +/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ +uint8_t const SPI_HALF_SPEED = 1; +/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */ +uint8_t const SPI_QUARTER_SPEED = 2; +/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */ +uint8_t const SPI_EIGHTH_SPEED = 3; +/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */ +uint8_t const SPI_SIXTEENTH_SPEED = 4; +//------------------------------------------------------------------------------ +/** init timeout ms */ +uint16_t const SD_INIT_TIMEOUT = 2000; +/** erase timeout ms */ +uint16_t const SD_ERASE_TIMEOUT = 10000; +/** read timeout ms */ +uint16_t const SD_READ_TIMEOUT = 300; +/** write time out ms */ +uint16_t const SD_WRITE_TIMEOUT = 600; +//------------------------------------------------------------------------------ +// SD card errors +/** timeout error for command CMD0 (initialize card in SPI mode) */ +uint8_t const SD_CARD_ERROR_CMD0 = 0X1; +/** CMD8 was not accepted - not a valid SD card*/ +uint8_t const SD_CARD_ERROR_CMD8 = 0X2; +/** card returned an error response for CMD12 (write stop) */ +uint8_t const SD_CARD_ERROR_CMD12 = 0X3; +/** card returned an error response for CMD17 (read block) */ +uint8_t const SD_CARD_ERROR_CMD17 = 0X4; +/** card returned an error response for CMD18 (read multiple block) */ +uint8_t const SD_CARD_ERROR_CMD18 = 0X5; +/** card returned an error response for CMD24 (write block) */ +uint8_t const SD_CARD_ERROR_CMD24 = 0X6; +/** WRITE_MULTIPLE_BLOCKS command failed */ +uint8_t const SD_CARD_ERROR_CMD25 = 0X7; +/** card returned an error response for CMD58 (read OCR) */ +uint8_t const SD_CARD_ERROR_CMD58 = 0X8; +/** SET_WR_BLK_ERASE_COUNT failed */ +uint8_t const SD_CARD_ERROR_ACMD23 = 0X9; +/** ACMD41 initialization process timeout */ +uint8_t const SD_CARD_ERROR_ACMD41 = 0XA; +/** card returned a bad CSR version field */ +uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB; +/** erase block group command failed */ +uint8_t const SD_CARD_ERROR_ERASE = 0XC; +/** card not capable of single block erase */ +uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD; +/** Erase sequence timed out */ +uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE; +/** card returned an error token instead of read data */ +uint8_t const SD_CARD_ERROR_READ = 0XF; +/** read CID or CSD failed */ +uint8_t const SD_CARD_ERROR_READ_REG = 0X10; +/** timeout while waiting for start of read data */ +uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11; +/** card did not accept STOP_TRAN_TOKEN */ +uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12; +/** card returned an error token as a response to a write operation */ +uint8_t const SD_CARD_ERROR_WRITE = 0X13; +/** attempt to write protected block zero */ +uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14; // REMOVE - not used +/** card did not go ready for a multiple block write */ +uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15; +/** card returned an error to a CMD13 status check after a write */ +uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16; +/** timeout occurred during write programming */ +uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17; +/** incorrect rate selected */ +uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18; +/** init() not called */ +uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19; +//------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +uint8_t const SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +uint8_t const SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +uint8_t const SD_CARD_TYPE_SDHC = 3; +/** + * define SOFTWARE_SPI to use bit-bang SPI + */ +//------------------------------------------------------------------------------ +#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) +#define SOFTWARE_SPI +#elif USE_SOFTWARE_SPI +#define SOFTWARE_SPI +#endif // MEGA_SOFT_SPI +//------------------------------------------------------------------------------ + +/** + * \class Sd2Card + * \brief Raw access to SD and SDHC flash memory cards. + */ +class Sd2Card { + public: + /** Construct an instance of Sd2Card. */ + Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} + uint32_t cardSize(); + bool erase(uint32_t firstBlock, uint32_t lastBlock); + bool eraseSingleBlockEnable(); + /** + * Set SD error code. + * \param[in] code value for error code. + */ + void error(uint8_t code) {errorCode_ = code;} + /** + * \return error code for last error. See Sd2Card.h for a list of error codes. + */ + int errorCode() const {return errorCode_;} + /** \return error data for last error. */ + int errorData() const {return status_;} + /** + * Initialize an SD flash memory card with default clock rate and chip + * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + * + * \return true for success or false for failure. + */ + bool init(uint8_t sckRateID = SPI_FULL_SPEED); + bool readBlock(uint32_t block, uint8_t* dst); + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(cid_t* cid) { + return readRegister(CMD10, cid); + } + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(csd_t* csd) { + return readRegister(CMD9, csd); + } + bool readData(uint8_t *dst); + bool readStart(uint32_t blockNumber); + bool readStop(); + bool setSckRate(uint8_t sckRateID); + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + int type() const {return type_;} + bool writeBlock(uint32_t blockNumber, const uint8_t* src); + bool writeData(const uint8_t* src); + bool writeStart(uint32_t blockNumber, uint32_t eraseCount); + bool writeStop(); + private: + //---------------------------------------------------------------------------- + uint8_t errorCode_; + uint8_t spiRate_; + uint8_t status_; + uint8_t type_; + // private functions + uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { + cardCommand(CMD55, 0); + return cardCommand(cmd, arg); + } + uint8_t cardCommand(uint8_t cmd, uint32_t arg); + + bool readData(uint8_t* dst, uint16_t count); + bool readRegister(uint8_t cmd, void* buf); + void chipSelectHigh(); + void chipSelectLow(); + void type(uint8_t value) {type_ = value;} + bool waitNotBusy(uint16_t timeoutMillis); + bool writeData(uint8_t token, const uint8_t* src); +}; +#endif // Sd2Card_h diff --git a/source-1.0L-F11/AVR/SdFat/SdBaseFile.cpp b/source-1.0L-F11/AVR/SdFat/SdBaseFile.cpp new file mode 100755 index 0000000..c6c6ef9 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdBaseFile.cpp @@ -0,0 +1,1824 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ + +#include +#include +//------------------------------------------------------------------------------ +// pointer to cwd directory +SdBaseFile* SdBaseFile::cwd_ = 0; +// callback function for date/time +void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0; +//------------------------------------------------------------------------------ +// add a cluster to a file +bool SdBaseFile::addCluster() { + if (!vol_->allocContiguous(1, &curCluster_)) goto fail; + + // if first cluster of file link to directory entry + if (firstCluster_ == 0) { + firstCluster_ = curCluster_; + flags_ |= F_FILE_DIR_DIRTY; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// Add a cluster to a directory file and zero the cluster. +// return with first block of cluster in the cache +bool SdBaseFile::addDirCluster() { + uint32_t block; + // max folder size + if (fileSize_/sizeof(dir_t) >= 0XFFFF) goto fail; + + if (!addCluster()) goto fail; + if (!vol_->cacheFlush()) goto fail; + + block = vol_->clusterStartBlock(curCluster_); + + // set cache to first block of cluster + vol_->cacheSetBlockNumber(block, true); + + // zero first block of cluster + memset(vol_->cacheBuffer_.data, 0, 512); + + // zero rest of cluster + for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) { + if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) goto fail; + } + // Increase directory file size by cluster size + fileSize_ += 512UL << vol_->clusterSizeShift_; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// cache a file's directory entry +// return pointer to cached entry or null for failure +dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { + if (!vol_->cacheRawBlock(dirBlock_, action)) goto fail; + return vol_->cache()->dir + dirIndex_; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +/** Close a file and force cached data and directory information + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include no file is open or an I/O error. + */ +bool SdBaseFile::close() { + bool rtn = sync(); + type_ = FAT_FILE_TYPE_CLOSED; + return rtn; +} +//------------------------------------------------------------------------------ +/** Check for contiguous file and return its raw block range. + * + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is not contiguous, file has zero length + * or an I/O error occurred. + */ +bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { + // error if no blocks + if (firstCluster_ == 0) goto fail; + + for (uint32_t c = firstCluster_; ; c++) { + uint32_t next; + if (!vol_->fatGet(c, &next)) goto fail; + + // check for contiguous + if (next != (c + 1)) { + // error if not end of chain + if (!vol_->isEOC(next)) goto fail; + *bgnBlock = vol_->clusterStartBlock(firstCluster_); + *endBlock = vol_->clusterStartBlock(c) + + vol_->blocksPerCluster_ - 1; + return true; + } + } + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Create and open a new contiguous file of a specified size. + * + * \note This function only supports short DOS 8.3 names. + * See open() for more information. + * + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a path contains + * an invalid DOS 8.3 file name, the FAT volume has not been initialized, + * a file is already open, the file already exists, the root + * directory is full or an I/O error. + * + */ +bool SdBaseFile::createContiguous(SdBaseFile* dirFile, + const char* path, uint32_t size) { + uint32_t count; + // don't allow zero length file + if (size == 0) goto fail; + if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) goto fail; + + // calculate number of clusters needed + count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; + + // allocate clusters + if (!vol_->allocContiguous(count, &firstCluster_)) { + remove(); + goto fail; + } + fileSize_ = size; + + // insure sync() will update dir entry + flags_ |= F_FILE_DIR_DIRTY; + + return sync(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Return a file's directory entry. + * + * \param[out] dir Location for return of the file's directory entry. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::dirEntry(dir_t* dir) { + dir_t* p; + // make sure fields on SD are correct + if (!sync()) goto fail; + + // read entry + p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) goto fail; + + // copy to caller's struct + memcpy(dir, p, sizeof(dir_t)); + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Format the name field of \a dir into the 13 byte array + * \a name in standard 8.3 short name format. + * + * \param[in] dir The directory structure containing the name. + * \param[out] name A 13 byte char array for the formatted name. + */ +void SdBaseFile::dirName(const dir_t& dir, char* name) { + uint8_t j = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) name[j++] = '.'; + name[j++] = dir.name[i]; + } + name[j] = 0; +} +//------------------------------------------------------------------------------ +/** Test for the existence of a file in a directory + * + * \param[in] name Name of the file to be tested for. + * + * The calling instance must be an open directory file. + * + * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory + * dirFile. + * + * \return true if the file exists else false. + */ +bool SdBaseFile::exists(const char* name) { + SdBaseFile file; + return file.open(this, name, O_READ); +} +//------------------------------------------------------------------------------ +/** + * Get a string from a file. + * + * fgets() reads bytes from a file into the array pointed to by \a str, until + * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str, + * or end-of-file is encountered. The string is then terminated + * with a null byte. + * + * fgets() deletes CR, '\\r', from the string. This insures only a '\\n' + * terminates the string for Windows text files which use CRLF for newline. + * + * \param[out] str Pointer to the array where the string is stored. + * \param[in] num Maximum number of characters to be read + * (including the final null byte). Usually the length + * of the array \a str is used. + * \param[in] delim Optional set of delimiters. The default is "\n". + * + * \return For success fgets() returns the length of the string in \a str. + * If no data is read, fgets() returns zero for EOF or -1 if an error occurred. + **/ +int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) { + char ch; + int16_t n = 0; + int16_t r = -1; + while ((n + 1) < num && (r = read(&ch, 1)) == 1) { + // delete CR + if (ch == '\r') continue; + str[n++] = ch; + if (!delim) { + if (ch == '\n') break; + } else { + if (strchr(delim, ch)) break; + } + } + if (r < 0) { + // read error + return -1; + } + str[n] = '\0'; + return n; +} +//------------------------------------------------------------------------------ +/** Get a file's name + * + * \param[out] name An array of 13 characters for the file's name. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::getFilename(char* name) { + if (!isOpen()) return false; + + if (isRoot()) { + name[0] = '/'; + name[1] = '\0'; + return true; + } + // cache entry + dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) return false; + + // format name + dirName(*p, name); + return true; +} +//------------------------------------------------------------------------------ +void SdBaseFile::getpos(fpos_t* pos) { + pos->position = curPosition_; + pos->cluster = curCluster_; +} +#if ARDUINO +//------------------------------------------------------------------------------ +/** List directory contents to Serial. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ +void SdBaseFile::ls(uint8_t flags) { + ls(&Serial, flags, 0); +} +//------------------------------------------------------------------------------ +/** List directory contents. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + * + * \param[in] indent Amount of space before file name. Used for recursive + * list to indicate subdirectory level. + */ +void SdBaseFile::ls(Print* pr, uint8_t flags, uint8_t indent) { + rewind(); + int8_t status; + while ((status = lsPrintNext(pr, flags, indent))) { + if (status > 1 && (flags & LS_R)) { + uint16_t index = curPosition()/32 - 1; + SdBaseFile s; + if (s.open(this, index, O_READ)) s.ls(pr, flags, indent + 2); + seekSet(32 * (index + 1)); + } + } +} +//------------------------------------------------------------------------------ +// saves 32 bytes on stack for ls recursion +// return 0 - EOF, 1 - normal file, or 2 - directory +int8_t SdBaseFile::lsPrintNext(Print *pr, uint8_t flags, uint8_t indent) { + dir_t dir; + uint8_t w = 0; + + while (1) { + if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0; + if (dir.name[0] == DIR_NAME_FREE) return 0; + + // skip deleted entry and entries for . and .. + if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.' + && DIR_IS_FILE_OR_SUBDIR(&dir)) break; + } + // indent for dir level + for (uint8_t i = 0; i < indent; i++) pr->write(' '); + + // print name + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + pr->write('.'); + w++; + } + pr->write(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir)) { + pr->write('/'); + w++; + } + if (flags & (LS_DATE | LS_SIZE)) { + while (w++ < 14) pr->write(' '); + } + // print modify date/time if requested + if (flags & LS_DATE) { + pr->write(' '); + printFatDate(pr, dir.lastWriteDate); + pr->write(' '); + printFatTime(pr, dir.lastWriteTime); + } + // print size if requested + if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { + pr->write(' '); + pr->print(dir.fileSize); + } + pr->println(); + return DIR_IS_FILE(&dir) ? 1 : 2; +} +#endif +//------------------------------------------------------------------------------ +// format directory name field from a 8.3 name string +bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { + uint8_t c; + uint8_t n = 7; // max index for part before dot + uint8_t i = 0; + // blank fill name and extension + while (i < 11) name[i++] = ' '; + i = 0; + while (*str != '\0' && *str != '/') { + c = *str++; + if (c == '.') { + if (n == 10) goto fail; // only one dot allowed + n = 10; // max index for full 8.3 name + i = 8; // place for extension + } else { + // illegal FAT characters + PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); + uint8_t b; + while ((b = pgm_read_byte(p++))) if (b == c) goto fail; + // check size and only allow ASCII printable characters + if (i > n || c < 0X21 || c > 0X7E)goto fail; + // only upper case allowed in 8.3 names - convert lower to upper + name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a'); + } + } + *ptr = str; + // must have a file name, extension is optional + return name[0] != ' '; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Make a new directory. + * + * \param[in] parent An open SdFat instance for the directory that will contain + * the new directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a parent is not a + * directory, \a path is invalid or already exists in \a parent. + */ +bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { + uint8_t dname[11]; + SdBaseFile dir1, dir2; + SdBaseFile* sub = &dir1; + SdBaseFile* start = parent; + + if (!parent || isOpen()) goto fail; + + if (*path == '/') { + while (*path == '/') path++; + if (!parent->isRoot()) { + if (!dir2.openRoot(parent->vol_)) goto fail; + parent = &dir2; + } + } + while (1) { + if (!make83Name(path, dname, &path)) goto fail; + while (*path == '/') path++; + if (!*path) break; + if (!sub->open(parent, dname, O_READ)) { + if (!pFlag || !sub->mkdir(parent, dname)) { + goto fail; + } + } + if (parent != start) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + } + return mkdir(parent, dname); + + fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { + uint32_t block; + dir_t d; + dir_t* p; + + if (!parent->isDir()) goto fail; + + // create a normal file + if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) goto fail; + + // convert file to directory + flags_ = O_READ; + type_ = FAT_FILE_TYPE_SUBDIR; + + // allocate and zero first cluster + if (!addDirCluster())goto fail; + + // force entry to SD + if (!sync()) goto fail; + + // cache entry - should already be in cache due to sync() call + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) goto fail; + + // change directory entry attribute + p->attributes = DIR_ATT_DIRECTORY; + + // make entry for '.' + memcpy(&d, p, sizeof(d)); + d.name[0] = '.'; + for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; + + // cache block for '.' and '..' + block = vol_->clusterStartBlock(firstCluster_); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; + + // copy '.' to block + memcpy(&vol_->cache()->dir[0], &d, sizeof(d)); + + // make entry for '..' + d.name[1] = '.'; + if (parent->isRoot()) { + d.firstClusterLow = 0; + d.firstClusterHigh = 0; + } else { + d.firstClusterLow = parent->firstCluster_ & 0XFFFF; + d.firstClusterHigh = parent->firstCluster_ >> 16; + } + // copy '..' to block + memcpy(&vol_->cache()->dir[1], &d, sizeof(d)); + + // write first block + return vol_->cacheFlush(); + + fail: + return false; +} +//------------------------------------------------------------------------------ + /** Open a file in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ + bool SdBaseFile::open(const char* path, uint8_t oflag) { + return open(cwd_, path, oflag); + } +//------------------------------------------------------------------------------ +/** Open a file or directory by name. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * O_READ - Open for reading. + * + * O_RDONLY - Same as O_READ. + * + * O_WRITE - Open for writing. + * + * O_WRONLY - Same as O_WRITE. + * + * O_RDWR - Open for reading and writing. + * + * O_APPEND - If set, the file offset shall be set to the end of the + * file prior to each write. + * + * O_AT_END - Set the initial position at the end of the file. + * + * O_CREAT - If the file exists, this flag has no effect except as noted + * under O_EXCL below. Otherwise, the file shall be created + * + * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + * + * O_SYNC - Call sync() after each write. This flag should not be used with + * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class. + * These functions do character at a time writes so sync() will be called + * after each byte. + * + * O_TRUNC - If the file exists and is a regular file, and the file is + * successfully opened and is not read only, its length shall be truncated to 0. + * + * WARNING: A given file must not be opened by more than one SdBaseFile object + * of file corruption may occur. + * + * \note Directory files must be opened read only. Write and truncation is + * not allowed for directory files. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a dirFile is not + * a directory, \a path is invalid, the file does not exist + * or can't be opened in the access mode specified by oflag. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) { + uint8_t dname[11]; + SdBaseFile dir1, dir2; + SdBaseFile *parent = dirFile; + SdBaseFile *sub = &dir1; + + if (!dirFile) goto fail; + + // error if already open + if (isOpen()) goto fail; + + if (*path == '/') { + while (*path == '/') path++; + if (!dirFile->isRoot()) { + if (!dir2.openRoot(dirFile->vol_)) goto fail; + parent = &dir2; + } + } + while (1) { + if (!make83Name(path, dname, &path)) goto fail; + while (*path == '/') path++; + if (!*path) break; + if (!sub->open(parent, dname, O_READ)) goto fail; + if (parent != dirFile) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + } + return open(parent, dname, oflag); + + fail: + return false; +} +//------------------------------------------------------------------------------ +// open with filename in dname +bool SdBaseFile::open(SdBaseFile* dirFile, + const uint8_t dname[11], uint8_t oflag) { + bool emptyFound = false; + bool fileFound = false; + uint8_t index; + dir_t* p; + + vol_ = dirFile->vol_; + + dirFile->rewind(); + // search for file + + while (dirFile->curPosition_ < dirFile->fileSize_) { + index = 0XF & (dirFile->curPosition_ >> 5); + p = dirFile->readDirCache(); + if (!p) goto fail; + + if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { + // remember first empty slot + if (!emptyFound) { + dirBlock_ = dirFile->vol_->cacheBlockNumber(); + dirIndex_ = index; + emptyFound = true; + } + // done if no entries follow + if (p->name[0] == DIR_NAME_FREE) break; + } else if (!memcmp(dname, p->name, 11)) { + fileFound = true; + break; + } + } + if (fileFound) { + // don't open existing file if O_EXCL + if (oflag & O_EXCL) goto fail; + } else { + // don't create unless O_CREAT and O_WRITE + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto fail; + if (emptyFound) { + index = dirIndex_; + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) goto fail; + } else { + if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto fail; + + // add and zero cluster for dirFile - first cluster is in cache for write + if (!dirFile->addDirCluster()) goto fail; + + // use first entry in cluster + p = dirFile->vol_->cache()->dir; + index = 0; + } + // initialize as empty file + memset(p, 0, sizeof(dir_t)); + memcpy(p->name, dname, 11); + + // set timestamps + if (dateTime_) { + // call user date/time function + dateTime_(&p->creationDate, &p->creationTime); + } else { + // use default date/time + p->creationDate = FAT_DEFAULT_DATE; + p->creationTime = FAT_DEFAULT_TIME; + } + p->lastAccessDate = p->creationDate; + p->lastWriteDate = p->creationDate; + p->lastWriteTime = p->creationTime; + + // write entry to SD + if (!dirFile->vol_->cacheFlush()) goto fail; + } + // open entry in cache + return openCachedEntry(index, oflag); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a file by index. + * + * \param[in] dirFile An open SdFat instance for the directory. + * + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) { + dir_t* p; + + vol_ = dirFile->vol_; + + // error if already open + if (isOpen() || !dirFile) goto fail; + + // don't open existing file if O_EXCL - user call error + if (oflag & O_EXCL) goto fail; + + // seek to location of entry + if (!dirFile->seekSet(32 * index)) goto fail; + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) goto fail; + + // error if empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_FREE || + p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + goto fail; + } + // open cached entry + return openCachedEntry(index & 0XF, oflag); + + fail: + return false; +} +//------------------------------------------------------------------------------ +// open a cached directory entry. Assumes vol_ is initialized +bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { + // location of entry in cache + dir_t* p = &vol_->cache()->dir[dirIndex]; + + // write or truncate is an error for a directory or read-only file + if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) { + if (oflag & (O_WRITE | O_TRUNC)) goto fail; + } + // remember location of directory entry on SD + dirBlock_ = vol_->cacheBlockNumber(); + dirIndex_ = dirIndex; + + // copy first cluster number for directory fields + firstCluster_ = (uint32_t)p->firstClusterHigh << 16; + firstCluster_ |= p->firstClusterLow; + + // make sure it is a normal file or subdirectory + if (DIR_IS_FILE(p)) { + fileSize_ = p->fileSize; + type_ = FAT_FILE_TYPE_NORMAL; + } else if (DIR_IS_SUBDIR(p)) { + if (!vol_->chainSize(firstCluster_, &fileSize_)) goto fail; + type_ = FAT_FILE_TYPE_SUBDIR; + } else { + goto fail; + } + // save open flags for read/write + flags_ = oflag & F_OFLAG; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + if ((oflag & O_TRUNC) && !truncate(0)) return false; + return oflag & O_AT_END ? seekEnd(0) : true; + + fail: + type_ = FAT_FILE_TYPE_CLOSED; + return false; +} +//------------------------------------------------------------------------------ +/** Open the next file or subdirectory in a directory. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { + dir_t* p; + uint8_t index; + + if (!dirFile) goto fail; + + // error if already open + if (isOpen()) goto fail; + + vol_ = dirFile->vol_; + + while (1) { + index = 0XF & (dirFile->curPosition_ >> 5); + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) goto fail; + + // done if last entry + if (p->name[0] == DIR_NAME_FREE) goto fail; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + continue; + } + // must be file or dir + if (DIR_IS_FILE_OR_SUBDIR(p)) { + return openCachedEntry(index, oflag); + } + } + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a directory's parent directory. + * + * \param[in] dir Parent of this directory will be opened. Must not be root. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::openParent(SdBaseFile* dir) { + dir_t entry; + dir_t* p; + SdBaseFile file; + uint32_t c; + uint32_t cluster; + uint32_t lbn; + // error if already open or dir is root or dir is not a directory + if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) goto fail; + vol_ = dir->vol_; + // position to '..' + if (!dir->seekSet(32)) goto fail; + // read '..' entry + if (dir->read(&entry, sizeof(entry)) != 32) goto fail; + // verify it is '..' + if (entry.name[0] != '.' || entry.name[1] != '.') goto fail; + // start cluster for '..' + cluster = entry.firstClusterLow; + cluster |= (uint32_t)entry.firstClusterHigh << 16; + if (cluster == 0) return openRoot(vol_); + // start block for '..' + lbn = vol_->clusterStartBlock(cluster); + // first block of parent dir + if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) { + goto fail; + } + p = &vol_->cacheBuffer_.dir[1]; + // verify name for '../..' + if (p->name[0] != '.' || p->name[1] != '.') goto fail; + // '..' is pointer to first cluster of parent. open '../..' to find parent + if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { + if (!file.openRoot(dir->volume())) goto fail; + } else { + if (!file.openCachedEntry(1, O_READ)) goto fail; + } + // search for parent in '../..' + do { + if (file.readDir(&entry) != 32) goto fail; + c = entry.firstClusterLow; + c |= (uint32_t)entry.firstClusterHigh << 16; + } while (c != cluster); + // open parent + return open(&file, file.curPosition()/32 - 1, O_READ); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a volume's root directory. + * + * \param[in] vol The FAT volume containing the root directory to be opened. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is already open, the FAT volume has + * not been initialized or it a FAT12 volume. + */ +bool SdBaseFile::openRoot(SdVolume* vol) { + // error if file is already open + if (isOpen()) goto fail; + + if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) { + type_ = FAT_FILE_TYPE_ROOT_FIXED; + firstCluster_ = 0; + fileSize_ = 32 * vol->rootDirEntryCount(); + } else if (vol->fatType() == 32) { + type_ = FAT_FILE_TYPE_ROOT32; + firstCluster_ = vol->rootDirStart(); + if (!vol->chainSize(firstCluster_, &fileSize_)) goto fail; + } else { + // volume is not initialized, invalid, or FAT12 without support + return false; + } + vol_ = vol; + // read only + flags_ = O_READ; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + + // root has no directory entry + dirBlock_ = 0; + dirIndex_ = 0; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ +int SdBaseFile::peek() { + fpos_t pos; + getpos(&pos); + int c = read(); + if (c >= 0) setpos(&pos); + return c; +} +#if ARDUINO +//------------------------------------------------------------------------------ +/** %Print the name field of a directory entry in 8.3 format to Serial. + * + * \param[in] dir The directory structure containing the name. + * \param[in] width Blank fill name if length is less than \a width. + * \param[in] printSlash Print '/' after directory names if true. + */ +void SdBaseFile::printDirName(const dir_t& dir, + uint8_t width, bool printSlash) { + printDirName(&Serial, dir, width, printSlash); +} +//------------------------------------------------------------------------------ +/** %Print the name field of a directory entry in 8.3 format. + * \param[in] pr Print stream for output. + * \param[in] dir The directory structure containing the name. + * \param[in] width Blank fill name if length is less than \a width. + * \param[in] printSlash Print '/' after directory names if true. + */ +void SdBaseFile::printDirName(Print* pr, const dir_t& dir, + uint8_t width, bool printSlash) { + uint8_t w = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + pr->write('.'); + w++; + } + pr->write(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir) && printSlash) { + pr->write('/'); + w++; + } + while (w < width) { + pr->write(' '); + w++; + } +} +//------------------------------------------------------------------------------ +// print uint8_t with width 2 +static void print2u(Print* pr, uint8_t v) { + if (v < 10) pr->write('0'); + pr->print(v, DEC); +} +//------------------------------------------------------------------------------ +/** %Print a directory date field to Serial. + * + * Format is yyyy-mm-dd. + * + * \param[in] fatDate The date field from a directory entry. + */ +void SdBaseFile::printFatDate(uint16_t fatDate) { + printFatDate(&Serial, fatDate); +} +//------------------------------------------------------------------------------ +/** %Print a directory date field. + * + * Format is yyyy-mm-dd. + * + * \param[in] pr Print stream for output. + * \param[in] fatDate The date field from a directory entry. + */ +void SdBaseFile::printFatDate(Print* pr, uint16_t fatDate) { + pr->print(FAT_YEAR(fatDate)); + pr->write('-'); + print2u(pr, FAT_MONTH(fatDate)); + pr->write('-'); + print2u(pr, FAT_DAY(fatDate)); +} +//------------------------------------------------------------------------------ +/** %Print a directory time field to Serial. + * + * Format is hh:mm:ss. + * + * \param[in] fatTime The time field from a directory entry. + */ +void SdBaseFile::printFatTime(uint16_t fatTime) { + printFatTime(&Serial, fatTime); +} +//------------------------------------------------------------------------------ +/** %Print a directory time field. + * + * Format is hh:mm:ss. + * + * \param[in] pr Print stream for output. + * \param[in] fatTime The time field from a directory entry. + */ +void SdBaseFile::printFatTime(Print* pr, uint16_t fatTime) { + print2u(pr, FAT_HOUR(fatTime)); + pr->write(':'); + print2u(pr, FAT_MINUTE(fatTime)); + pr->write(':'); + print2u(pr, FAT_SECOND(fatTime)); +} +//------------------------------------------------------------------------------ +/** Print a file's name to Serial + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::printName() { + char name[13]; + if (!getFilename(name)) return false; + Serial.print(name); + return true; +} +#endif +//------------------------------------------------------------------------------ +/** Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ +int16_t SdBaseFile::read() { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; +} +//------------------------------------------------------------------------------ +/** Read data from a file starting at the current position. + * + * \param[out] buf Pointer to the location that will receive the data. + * + * \param[in] nbyte Maximum number of bytes to read. + * + * \return For success read() returns the number of bytes read. + * A value less than \a nbyte, including zero, will be returned + * if end of file is reached. + * If an error occurs, read() returns -1. Possible errors include + * read() called before a file has been opened, corrupt file system + * or an I/O error occurred. + */ +int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { + uint8_t* dst = reinterpret_cast(buf); + uint16_t offset; + uint16_t toRead; + uint32_t block; // raw device block number + + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) goto fail; + + // max bytes left in file + if (nbyte >= (fileSize_ - curPosition_)) { + nbyte = fileSize_ - curPosition_; + } + // amount left to read + toRead = nbyte; + while (toRead > 0) { + offset = curPosition_ & 0X1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + block = vol_->rootDirStart() + (curPosition_ >> 9); + } else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; + } + } + block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + uint16_t n = toRead; + + // amount to be read from current block + if (n > (512 - offset)) n = 512 - offset; + + // no buffering needed if n == 512 + if (n == 512 && block != vol_->cacheBlockNumber()) { + if (!vol_->readBlock(block, dst)) goto fail; + } else { + // read block to cache and copy data to caller + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; + uint8_t* src = vol_->cache()->data + offset; + memcpy(dst, src, n); + } + dst += n; + curPosition_ += n; + toRead -= n; + } + return nbyte; + + fail: + return -1; +} +//------------------------------------------------------------------------------ +/** Read the next directory entry from a directory file. + * + * \param[out] dir The dir_t struct that will receive the data. + * + * \return For success readDir() returns the number of bytes read. + * A value of zero will be returned if end of file is reached. + * If an error occurs, readDir() returns -1. Possible errors include + * readDir() called before a directory has been opened, this is not + * a directory file or an I/O error occurred. + */ +int8_t SdBaseFile::readDir(dir_t* dir) { + int16_t n; + // if not a directory file or miss-positioned return an error + if (!isDir() || (0X1F & curPosition_)) return -1; + + while (1) { + n = read(dir, sizeof(dir_t)); + if (n != sizeof(dir_t)) return n == 0 ? 0 : -1; + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) return 0; + // skip empty entries and entry for . and .. + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue; + // return if normal file or subdirectory + if (DIR_IS_FILE_OR_SUBDIR(dir)) return n; + } +} +//------------------------------------------------------------------------------ +// Read next directory entry into the cache +// Assumes file is correctly positioned +dir_t* SdBaseFile::readDirCache() { + uint8_t i; + // error if not directory + if (!isDir()) goto fail; + + // index of entry in cache + i = (curPosition_ >> 5) & 0XF; + + // use read to locate and cache block + if (read() < 0) goto fail; + + // advance to next entry + curPosition_ += 31; + + // return pointer to entry + return vol_->cache()->dir + i; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file read-only, is a directory, + * or an I/O error occurred. + */ +bool SdBaseFile::remove() { + dir_t* d; + // free any clusters - will fail if read-only or directory + if (!truncate(0)) goto fail; + + // cache directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // set this file closed + type_ = FAT_FILE_TYPE_CLOSED; + + // write entry to SD + return vol_->cacheFlush(); + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \param[in] dirFile The directory that contains the file. + * \param[in] path Path for the file to be removed. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is a directory, is read only, + * \a dirFile is not a directory, \a path is not found + * or an I/O error occurred. + */ +bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { + SdBaseFile file; + if (!file.open(dirFile, path, O_WRITE)) goto fail; + return file.remove(); + + fail: + // can't set iostate - static function + return false; +} +//------------------------------------------------------------------------------ +/** Rename a file or subdirectory. + * + * \param[in] dirFile Directory for the new path. + * \param[in] newPath New path name for the file/directory. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a dirFile is not open or is not a directory + * file, newPath is invalid or already exists, or an I/O error occurs. + */ +bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { + dir_t entry; + uint32_t dirCluster = 0; + SdBaseFile file; + dir_t* d; + + // must be an open file or subdirectory + if (!(isFile() || isSubDir())) goto fail; + + // can't move file + if (vol_ != dirFile->vol_) goto fail; + + // sync() and cache directory entry + sync(); + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // save directory entry + memcpy(&entry, d, sizeof(entry)); + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // make directory entry for new path + if (isFile()) { + if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) { + goto restore; + } + } else { + // don't create missing path prefix components + if (!file.mkdir(dirFile, newPath, false)) { + goto restore; + } + // save cluster containing new dot dot + dirCluster = file.firstCluster_; + } + // change to new directory entry + dirBlock_ = file.dirBlock_; + dirIndex_ = file.dirIndex_; + + // mark closed to avoid possible destructor close call + file.type_ = FAT_FILE_TYPE_CLOSED; + + // cache new directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // copy all but name field to new directory entry + memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name)); + + // update dot dot if directory + if (dirCluster) { + // get new dot dot + uint32_t block = vol_->clusterStartBlock(dirCluster); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; + memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry)); + + // free unused cluster + if (!vol_->freeChain(dirCluster)) goto fail; + + // store new dot dot + block = vol_->clusterStartBlock(firstCluster_); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; + memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry)); + } + return vol_->cacheFlush(); + + restore: + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + // restore entry + d->name[0] = entry.name[0]; + vol_->cacheFlush(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a directory file. + * + * The directory file will be removed only if it is empty and is not the + * root directory. rmdir() follows DOS and Windows and ignores the + * read-only attribute for the directory. + * + * \note This function should not be used to delete the 8.3 version of a + * directory that has a long name. For example if a directory has the + * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is not a directory, is the root + * directory, is not empty, or an I/O error occurred. + */ +bool SdBaseFile::rmdir() { + // must be open subdirectory + if (!isSubDir()) goto fail; + + rewind(); + + // make sure directory is empty + while (curPosition_ < fileSize_) { + dir_t* p = readDirCache(); + if (!p) goto fail; + // done if past last used entry + if (p->name[0] == DIR_NAME_FREE) break; + // skip empty slot, '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + // error not empty + if (DIR_IS_FILE_OR_SUBDIR(p)) goto fail; + } + // convert empty directory to normal file for remove + type_ = FAT_FILE_TYPE_NORMAL; + flags_ |= O_WRITE; + return remove(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Recursively delete a directory and all contained files. + * + * This is like the Unix/Linux 'rm -rf *' if called with the root directory + * hence the name. + * + * Warning - This will remove all contents of the directory including + * subdirectories. The directory will then be removed if it is not root. + * The read-only attribute for files will be ignored. + * + * \note This function should not be used to delete the 8.3 version of + * a directory that has a long name. See remove() and rmdir(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::rmRfStar() { + uint16_t index; + SdBaseFile f; + rewind(); + while (curPosition_ < fileSize_) { + // remember position + index = curPosition_/32; + + dir_t* p = readDirCache(); + if (!p) goto fail; + + // done if past last entry + if (p->name[0] == DIR_NAME_FREE) break; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + + // skip if part of long file name or volume label in root + if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; + + if (!f.open(this, index, O_READ)) goto fail; + if (f.isSubDir()) { + // recursively delete + if (!f.rmRfStar()) goto fail; + } else { + // ignore read-only + f.flags_ |= O_WRITE; + if (!f.remove()) goto fail; + } + // position to next entry if required + if (curPosition_ != (32*(index + 1))) { + if (!seekSet(32*(index + 1))) goto fail; + } + } + // don't try to delete root + if (!isRoot()) { + if (!rmdir()) goto fail; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { + type_ = FAT_FILE_TYPE_CLOSED; + writeError = false; + open(path, oflag); +} +//------------------------------------------------------------------------------ +/** Sets a file's position. + * + * \param[in] pos The new position in bytes from the beginning of the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::seekSet(uint32_t pos) { + uint32_t nCur; + uint32_t nNew; + // error if file not open or seek past end of file + if (!isOpen() || pos > fileSize_) goto fail; + + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + curPosition_ = pos; + goto done; + } + if (pos == 0) { + // set position to start of file + curCluster_ = 0; + curPosition_ = 0; + goto done; + } + // calculate cluster index for cur and new position + nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); + nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); + + if (nNew < nCur || curPosition_ == 0) { + // must follow chain from first cluster + curCluster_ = firstCluster_; + } else { + // advance from curPosition + nNew -= nCur; + } + while (nNew--) { + if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; + } + curPosition_ = pos; + + done: + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +void SdBaseFile::setpos(fpos_t* pos) { + curPosition_ = pos->position; + curCluster_ = pos->cluster; +} +//------------------------------------------------------------------------------ +/** The sync() call causes all modified data and directory fields + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include a call to sync() before a file has been + * opened or an I/O error. + */ +bool SdBaseFile::sync() { + // only allow open files and directories + if (!isOpen()) goto fail; + + if (flags_ & F_FILE_DIR_DIRTY) { + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + // check for deleted by another open file object + if (!d || d->name[0] == DIR_NAME_DELETED) goto fail; + + // do not set filesize for dir files + if (!isDir()) d->fileSize = fileSize_; + + // update first cluster fields + d->firstClusterLow = firstCluster_ & 0XFFFF; + d->firstClusterHigh = firstCluster_ >> 16; + + // set modify time if user supplied a callback date/time function + if (dateTime_) { + dateTime_(&d->lastWriteDate, &d->lastWriteTime); + d->lastAccessDate = d->lastWriteDate; + } + // clear directory dirty + flags_ &= ~F_FILE_DIR_DIRTY; + } + return vol_->cacheFlush(); + + fail: + writeError = true; + return false; +} +//------------------------------------------------------------------------------ +/** Copy a file's timestamps + * + * \param[in] file File to copy timestamps from. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(SdBaseFile* file) { + dir_t* d; + dir_t dir; + + // get timestamps + if (!file->dirEntry(&dir)) goto fail; + + // update directory fields + if (!sync()) goto fail; + + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // copy timestamps + d->lastAccessDate = dir.lastAccessDate; + d->creationDate = dir.creationDate; + d->creationTime = dir.creationTime; + d->creationTimeTenths = dir.creationTimeTenths; + d->lastWriteDate = dir.lastWriteDate; + d->lastWriteTime = dir.lastWriteTime; + + // write back entry + return vol_->cacheFlush(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Set a file's timestamps in its directory entry. + * + * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * T_ACCESS - Set the file's last access date. + * + * T_CREATE - Set the file's creation date and time. + * + * T_WRITE - Set the file's last write/modification date and time. + * + * \param[in] year Valid range 1980 - 2107 inclusive. + * + * \param[in] month Valid range 1 - 12 inclusive. + * + * \param[in] day Valid range 1 - 31 inclusive. + * + * \param[in] hour Valid range 0 - 23 inclusive. + * + * \param[in] minute Valid range 0 - 59 inclusive. + * + * \param[in] second Valid range 0 - 59 inclusive + * + * \note It is possible to set an invalid date since there is no check for + * the number of days in a month. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, + uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + uint16_t dirDate; + uint16_t dirTime; + dir_t* d; + + if (!isOpen() + || year < 1980 + || year > 2107 + || month < 1 + || month > 12 + || day < 1 + || day > 31 + || hour > 23 + || minute > 59 + || second > 59) { + goto fail; + } + // update directory entry + if (!sync()) goto fail; + + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + dirDate = FAT_DATE(year, month, day); + dirTime = FAT_TIME(hour, minute, second); + if (flags & T_ACCESS) { + d->lastAccessDate = dirDate; + } + if (flags & T_CREATE) { + d->creationDate = dirDate; + d->creationTime = dirTime; + // seems to be units of 1/100 second not 1/10 as Microsoft states + d->creationTimeTenths = second & 1 ? 100 : 0; + } + if (flags & T_WRITE) { + d->lastWriteDate = dirDate; + d->lastWriteTime = dirTime; + } + return vol_->cacheFlush(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +bool SdBaseFile::truncate(uint32_t length) { + uint32_t newPos; + // error if not a normal file or read-only + if (!isFile() || !(flags_ & O_WRITE)) goto fail; + + // error if length is greater than current size + if (length > fileSize_) goto fail; + + // fileSize and length are zero - nothing to do + if (fileSize_ == 0) return true; + + // remember position for seek after truncation + newPos = curPosition_ > length ? length : curPosition_; + + // position to last cluster in truncated file + if (!seekSet(length)) goto fail; + + if (length == 0) { + // free all clusters + if (!vol_->freeChain(firstCluster_)) goto fail; + firstCluster_ = 0; + } else { + uint32_t toFree; + if (!vol_->fatGet(curCluster_, &toFree)) goto fail; + + if (!vol_->isEOC(toFree)) { + // free extra clusters + if (!vol_->freeChain(toFree)) goto fail; + + // current cluster is end of chain + if (!vol_->fatPutEOC(curCluster_)) goto fail; + } + } + fileSize_ = length; + + // need to update directory entry + flags_ |= F_FILE_DIR_DIRTY; + + if (!sync()) goto fail; + + // set file to correct position + return seekSet(newPos); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \a nbyte. If an error occurs, write() returns -1. Possible errors + * include write() is called before a file has been opened, write is called + * for a read-only file, device is full, a corrupt file system or an I/O error. + * + */ +int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) { + // convert void* to uint8_t* - must be before goto statements + const uint8_t* src = reinterpret_cast(buf); + + // number of bytes left to write - must be before goto statements + uint16_t nToWrite = nbyte; + + // error if not a normal file or is read-only + if (!isFile() || !(flags_ & O_WRITE)) goto fail; + + // seek to end of file if append flag + if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { + if (!seekEnd()) goto fail; + } + + while (nToWrite > 0) { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + uint16_t blockOffset = curPosition_ & 0X1FF; + if (blockOfCluster == 0 && blockOffset == 0) { + // start of new cluster + if (curCluster_ == 0) { + if (firstCluster_ == 0) { + // allocate first cluster of file + if (!addCluster()) goto fail; + } else { + curCluster_ = firstCluster_; + } + } else { + uint32_t next; + if (!vol_->fatGet(curCluster_, &next)) goto fail; + if (vol_->isEOC(next)) { + // add cluster if at end of chain + if (!addCluster()) goto fail; + } else { + curCluster_ = next; + } + } + } + // max space in block + uint16_t n = 512 - blockOffset; + + // lesser of space and amount to write + if (n > nToWrite) n = nToWrite; + + // block for data write + uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + if (n == 512) { + // full block - don't need to use cache + if (vol_->cacheBlockNumber() == block) { + // invalidate cache if block is in cache + vol_->cacheSetBlockNumber(0XFFFFFFFF, false); + } + if (!vol_->writeBlock(block, src)) goto fail; + } else { + if (blockOffset == 0 && curPosition_ >= fileSize_) { + // start of new block don't need to read into cache + if (!vol_->cacheFlush()) goto fail; + // set cache dirty and SD address of block + vol_->cacheSetBlockNumber(block, true); + } else { + // rewrite part of block + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; + } + uint8_t* dst = vol_->cache()->data + blockOffset; + memcpy(dst, src, n); + } + curPosition_ += n; + src += n; + nToWrite -= n; + } + if (curPosition_ > fileSize_) { + // update fileSize and insure sync will update dir entry + fileSize_ = curPosition_; + flags_ |= F_FILE_DIR_DIRTY; + } else if (dateTime_ && nbyte) { + // insure sync will update modified date and time + flags_ |= F_FILE_DIR_DIRTY; + } + + if (flags_ & O_SYNC) { + if (!sync()) goto fail; + } + return nbyte; + + fail: + // return for write error + writeError = true; + return -1; +} +//------------------------------------------------------------------------------ +// suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) +void (*SdBaseFile::oldDateTime_)(uint16_t& date, uint16_t& time) = 0; // NOLINT +#endif // ALLOW_DEPRECATED_FUNCTIONS diff --git a/source-1.0L-F11/AVR/SdFat/SdBaseFile.h b/source-1.0L-F11/AVR/SdFat/SdBaseFile.h new file mode 100755 index 0000000..4467ec8 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdBaseFile.h @@ -0,0 +1,492 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdBaseFile_h +#define SdBaseFile_h +/** + * \file + * \brief SdBaseFile class + */ +#include +#include +#include +//------------------------------------------------------------------------------ +/** + * \struct fpos_t + * \brief internal type for istream + * do not use in user apps + */ +struct fpos_t { + /** stream position */ + uint32_t position; + /** cluster for position */ + uint32_t cluster; + fpos_t() : position(0), cluster(0) {} +}; + +// use the gnu style oflag in open() +/** open() oflag for reading */ +uint8_t const O_READ = 0X01; +/** open() oflag - same as O_IN */ +uint8_t const O_RDONLY = O_READ; +/** open() oflag for write */ +uint8_t const O_WRITE = 0X02; +/** open() oflag - same as O_WRITE */ +uint8_t const O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +uint8_t const O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +uint8_t const O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +uint8_t const O_APPEND = 0X04; +/** synchronous writes - call sync() after each write */ +uint8_t const O_SYNC = 0X08; +/** truncate the file to zero length */ +uint8_t const O_TRUNC = 0X10; +/** set the initial position at the end of the file */ +uint8_t const O_AT_END = 0X20; +/** create the file if nonexistent */ +uint8_t const O_CREAT = 0X40; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +uint8_t const O_EXCL = 0X80; + +// SdBaseFile class static and const definitions +// flags for ls() +/** ls() flag to print modify date */ +uint8_t const LS_DATE = 1; +/** ls() flag to print file size */ +uint8_t const LS_SIZE = 2; +/** ls() flag for recursive list of subdirectories */ +uint8_t const LS_R = 4; + + +// flags for timestamp +/** set the file's last access date */ +uint8_t const T_ACCESS = 1; +/** set the file's creation date and time */ +uint8_t const T_CREATE = 2; +/** Set the file's write date and time */ +uint8_t const T_WRITE = 4; +// values for type_ +/** This file has not been opened. */ +uint8_t const FAT_FILE_TYPE_CLOSED = 0; +/** A normal file */ +uint8_t const FAT_FILE_TYPE_NORMAL = 1; +/** A FAT12 or FAT16 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2; +/** A FAT32 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT32 = 3; +/** A subdirectory file*/ +uint8_t const FAT_FILE_TYPE_SUBDIR = 4; +/** Test value for directory type */ +uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; + +/** date field for FAT directory entry + * \param[in] year [1980,2107] + * \param[in] month [1,12] + * \param[in] day [1,31] + * + * \return Packed date for dir_t entry. + */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted year [1980,2107] + */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted month [1,12] + */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted day [1,31] + */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0X1F; +} +/** time field for FAT directory entry + * \param[in] hour [0,23] + * \param[in] minute [0,59] + * \param[in] second [0,59] + * + * \return Packed time for dir_t entry. + */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted hour [0,23] + */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted minute [0,59] + */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return(fatTime >> 5) & 0X3F; +} +/** second part of FAT directory time field + * Note second/2 is stored in packed time. + * + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted second [0,58] + */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2*(fatTime & 0X1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +uint16_t const FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** + * \class SdBaseFile + * \brief Base class for SdFile with Print and C++ streams. + */ +class SdBaseFile { + public: + /** Create an instance. */ + SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} + SdBaseFile(const char* path, uint8_t oflag); + ~SdBaseFile() {if(isOpen()) close();} + /** + * writeError is set to true if an error occurs during a write(). + * Set writeError to false before calling print() and/or write() and check + * for true after calls to print() and/or write(). + */ + bool writeError; + //---------------------------------------------------------------------------- + // helpers for stream classes + /** get position for streams + * \param[out] pos struct to receive position + */ + void getpos(fpos_t* pos); + /** set position for streams + * \param[out] pos struct with value for new position + */ + void setpos(fpos_t* pos); + //---------------------------------------------------------------------------- + bool close(); + bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + bool createContiguous(SdBaseFile* dirFile, + const char* path, uint32_t size); + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster() const {return curCluster_;} + /** \return The current position for a file or directory. */ + uint32_t curPosition() const {return curPosition_;} + /** \return Current working directory */ + static SdBaseFile* cwd() {return cwd_;} + /** Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + dateTime_ = dateTime; + } + /** Cancel the date/time callback function. */ + static void dateTimeCallbackCancel() {dateTime_ = 0;} + bool dirEntry(dir_t* dir); + static void dirName(const dir_t& dir, char* name); + bool exists(const char* name); + int16_t fgets(char* str, int16_t num, char* delim = 0); + /** \return The total number of bytes in a file or directory. */ + uint32_t fileSize() const {return fileSize_;} + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster() const {return firstCluster_;} + bool getFilename(char* name); + /** \return True if this is a directory else false. */ + bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} + /** \return True if this is a normal file else false. */ + bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;} + /** \return True if this is an open file/directory else false. */ + bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;} + /** \return True if this is a subdirectory else false. */ + bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;} + /** \return True if this is the root directory. */ + bool isRoot() const { + return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; + } +#if ARDUINO + void ls(Print* pr, uint8_t flags = 0, uint8_t indent = 0); + void ls(uint8_t flags = 0); +#endif + bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true); + // alias for backward compactability + bool makeDir(SdBaseFile* dir, const char* path) { + return mkdir(dir, path, false); + } + bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + bool open(const char* path, uint8_t oflag = O_READ); + bool openNext(SdBaseFile* dirFile, uint8_t oflag); + bool openRoot(SdVolume* vol); + int peek(); +#if ARDUINO + static void printFatDate(uint16_t fatDate); + static void printFatDate(Print* pr, uint16_t fatDate); + static void printFatTime(uint16_t fatTime); + static void printFatTime(Print* pr, uint16_t fatTime); + bool printName(); +#endif + int16_t read(); + int16_t read(void* buf, uint16_t nbyte); + int8_t readDir(dir_t* dir); + static bool remove(SdBaseFile* dirFile, const char* path); + bool remove(); + /** Set the file's current position to zero. */ + void rewind() {seekSet(0);} + bool rename(SdBaseFile* dirFile, const char* newPath); + bool rmdir(); + // for backward compatibility + bool rmDir() {return rmdir();} + bool rmRfStar(); + /** Set the files position to current position + \a pos. See seekSet(). + * \param[in] offset The new position in bytes from the current position. + * \return true for success or false for failure. + */ + bool seekCur(int32_t offset) { + return seekSet(curPosition_ + offset); + } + /** Set the files position to end-of-file + \a offset. See seekSet(). + * \param[in] offset The new position in bytes from end-of-file. + * \return true for success or false for failure. + */ + bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);} + bool seekSet(uint32_t pos); + bool sync(); + bool timestamp(SdBaseFile* file); + bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + /** Type of file. You should use isFile() or isDir() instead of type() + * if possible. + * + * \return The file or directory type. + */ + uint8_t type() const {return type_;} + bool truncate(uint32_t size); + /** \return SdVolume that contains this file. */ + SdVolume* volume() const {return vol_;} + int16_t write(const void* buf, uint16_t nbyte); +//------------------------------------------------------------------------------ + private: + // allow SdFat to set cwd_ + friend class SdFat; + // global pointer to cwd dir + static SdBaseFile* cwd_; + // data time callback function + static void (*dateTime_)(uint16_t* date, uint16_t* time); + // bits defined in flags_ + // should be 0X0F + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // sync of directory entry required + static uint8_t const F_FILE_DIR_DIRTY = 0X80; + + // private data + uint8_t flags_; // See above for definition of flags_ bits + uint8_t fstate_; // error and eof indicator + uint8_t type_; // type of file see above for values + uint32_t curCluster_; // cluster for current file position + uint32_t curPosition_; // current file position in bytes from beginning + uint32_t dirBlock_; // block for this files directory entry + uint8_t dirIndex_; // index of directory entry in dirBlock + uint32_t fileSize_; // file size in bytes + uint32_t firstCluster_; // first cluster of file + SdVolume* vol_; // volume where file is located + + /** experimental don't use */ + bool openParent(SdBaseFile* dir); + // private functions + bool addCluster(); + bool addDirCluster(); + dir_t* cacheDirEntry(uint8_t action); +#if ARDUINO + int8_t lsPrintNext(Print *pr, uint8_t flags, uint8_t indent); +#endif + static bool make83Name(const char* str, uint8_t* name, const char** ptr); + bool mkdir(SdBaseFile* parent, const uint8_t dname[11]); + bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag); + bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags); + dir_t* readDirCache(); +//------------------------------------------------------------------------------ +// to be deleted + static void printDirName(const dir_t& dir, + uint8_t width, bool printSlash); +#if ARDUINO + static void printDirName(Print* pr, const dir_t& dir, + uint8_t width, bool printSlash); +#endif +//------------------------------------------------------------------------------ +// Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + public: + /** \deprecated Use: + * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * \return true for success or false for failure. + */ + bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + return contiguousRange(&bgnBlock, &endBlock); + } + /** \deprecated Use: + * bool createContiguous(SdBaseFile* dirFile, + * const char* path, uint32_t size) + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * \return true for success or false for failure. + */ + bool createContiguous(SdBaseFile& dirFile, // NOLINT + const char* path, uint32_t size) { + return createContiguous(&dirFile, path, size); + } + /** \deprecated Use: + * static void dateTimeCallback( + * void (*dateTime)(uint16_t* date, uint16_t* time)); + * \param[in] dateTime The user's call back function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT + oldDateTime_ = dateTime; + dateTime_ = dateTime ? oldToNew : 0; + } + /** \deprecated Use: bool dirEntry(dir_t* dir); + * \param[out] dir Location for return of the file's directory entry. + * \return true for success or false for failure. + */ + bool dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT + /** \deprecated Use: + * bool mkdir(SdBaseFile* dir, const char* path); + * \param[in] dir An open SdFat instance for the directory that will contain + * the new directory. + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * \return true for success or false for failure. + */ + bool mkdir(SdBaseFile& dir, const char* path) { // NOLINT + return mkdir(&dir, path); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, // NOLINT + const char* path, uint8_t oflag) { + return open(&dirFile, path, oflag); + } + /** \deprecated Do not use in new apps + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, const char* path) { // NOLINT + return open(dirFile, path, O_RDWR); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory. + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + return open(&dirFile, index, oflag); + } + /** \deprecated Use: bool openRoot(SdVolume* vol); + * \param[in] vol The FAT volume containing the root directory to be opened. + * \return true for success or false for failure. + */ + bool openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT + /** \deprecated Use: int8_t readDir(dir_t* dir); + * \param[out] dir The dir_t struct that will receive the data. + * \return bytes read for success zero for eof or -1 for failure. + */ + int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT + /** \deprecated Use: + * static uint8_t remove(SdBaseFile* dirFile, const char* path); + * \param[in] dirFile The directory that contains the file. + * \param[in] path The name of the file to be removed. + * \return true for success or false for failure. + */ + static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT + return remove(&dirFile, path); + } +//------------------------------------------------------------------------------ +// rest are private + private: + static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT + static void oldToNew(uint16_t* date, uint16_t* time) { + uint16_t d; + uint16_t t; + oldDateTime_(d, t); + *date = d; + *time = t; + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; + +#endif // SdBaseFile_h diff --git a/source-1.0L-F11/AVR/SdFat/SdFat.cpp b/source-1.0L-F11/AVR/SdFat/SdFat.cpp new file mode 100755 index 0000000..845f3f4 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdFat.cpp @@ -0,0 +1,332 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#include +//#include +//------------------------------------------------------------------------------ +/** Change a volume's working directory to root + * + * Changes the volume's working directory to the SD's root directory. + * Optionally set the current working directory to the volume's + * working directory. + * + * \param[in] set_cwd Set the current working directory to this volume's + * working directory if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::chdir(bool set_cwd) { + if (set_cwd) SdBaseFile::cwd_ = &vwd_; + vwd_.close(); + return vwd_.openRoot(&vol_); +} +//------------------------------------------------------------------------------ +/** Change a volume's working directory + * + * Changes the volume working directory to the \a path subdirectory. + * Optionally set the current working directory to the volume's + * working directory. + * + * Example: If the volume's working directory is "/DIR", chdir("SUB") + * will change the volume's working directory from "/DIR" to "/DIR/SUB". + * + * If path is "/", the volume's working directory will be changed to the + * root directory + * + * \param[in] path The name of the subdirectory. + * + * \param[in] set_cwd Set the current working directory to this volume's + * working directory if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::chdir(const char *path, bool set_cwd) { + SdBaseFile dir; + if (path[0] == '/' && path[1] == '\0') return chdir(set_cwd); + if (!dir.open(&vwd_, path, O_READ)) goto fail; + if (!dir.isDir()) goto fail; + vwd_ = dir; + if (set_cwd) SdBaseFile::cwd_ = &vwd_; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Set the current working directory to a volume's working directory. + * + * This is useful with multiple SD cards. + * + * The current working directory is changed to this volume's working directory. + * + * This is like the Windows/DOS \: command. + */ +void SdFat::chvol() { + SdBaseFile::cwd_ = &vwd_; +} +#if ARDUINO +//------------------------------------------------------------------------------ +/** %Print any SD error code and halt. */ +void SdFat::errorHalt() { + errorPrint(); + while (1); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code, and halt. + * + * \param[in] msg Message to print. + */ +void SdFat::errorHalt(char const* msg) { + errorPrint(msg); + while (1); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code, and halt. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::errorHalt_P(PGM_P msg) { + errorPrint_P(msg); + while (1); +} +//------------------------------------------------------------------------------ +/** %Print any SD error code. */ +void SdFat::errorPrint() { + if (!card_.errorCode()) return; + PgmPrint("SD errorCode: 0X"); + Serial.println(card_.errorCode(), HEX); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code. + * + * \param[in] msg Message to print. + */ +void SdFat::errorPrint(char const* msg) { + PgmPrint("error: "); + Serial.println(msg); + errorPrint(); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::errorPrint_P(PGM_P msg) { + PgmPrint("error: "); + SerialPrintln_P(msg); + errorPrint(); +} +#endif +//------------------------------------------------------------------------------ +/** + * Test for the existence of a file. + * + * \param[in] name Name of the file to be tested for. + * + * \return true if the file exists else false. + */ +bool SdFat::exists(const char* name) { + return vwd_.exists(name); +} +//------------------------------------------------------------------------------ +/** + * Initialize an SdFat object. + * + * Initializes the SD card, SD volume, and root directory. + * + * \param[in] sckRateID value for SPI SCK rate. See Sd2Card::init(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::init(uint8_t sckRateID) { + return card_.init(sckRateID) && vol_.init(&card_) && chdir(1); +} +#if ARDUINO +//------------------------------------------------------------------------------ +/** %Print error details and halt after SdFat::init() fails. */ +void SdFat::initErrorHalt() { + initErrorPrint(); + while (1); +} +//------------------------------------------------------------------------------ +/**Print message, error details, and halt after SdFat::init() fails. + * + * \param[in] msg Message to print. + */ +void SdFat::initErrorHalt(char const *msg) { + Serial.println(msg); + initErrorHalt(); +} +//------------------------------------------------------------------------------ +/**Print message, error details, and halt after SdFat::init() fails. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::initErrorHalt_P(PGM_P msg) { + SerialPrintln_P(msg); + initErrorHalt(); +} +//------------------------------------------------------------------------------ +/** Print error details after SdFat::init() fails. */ +void SdFat::initErrorPrint() { + if (card_.errorCode()) { + PgmPrintln("Can't access SD card. Do not reformat."); + if (card_.errorCode() == SD_CARD_ERROR_CMD0) { + PgmPrintln("No card, wrong chip select pin, or SPI problem?"); + } + errorPrint(); + } else if (vol_.fatType() == 0) { + PgmPrintln("Invalid format, reformat SD."); + } else if (!vwd_.isOpen()) { + PgmPrintln("Can't open root directory."); + } else { + PgmPrintln("No error found."); + } +} +//------------------------------------------------------------------------------ +/**Print message and error details and halt after SdFat::init() fails. + * + * \param[in] msg Message to print. + */ +void SdFat::initErrorPrint(char const *msg) { + Serial.println(msg); + initErrorPrint(); +} +//------------------------------------------------------------------------------ +/**Print message and error details after SdFat::init() fails. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::initErrorPrint_P(PGM_P msg) { + SerialPrintln_P(msg); + initErrorHalt(); +} +//------------------------------------------------------------------------------ +/** List the directory contents of the volume working directory to Serial. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ +void SdFat::ls(uint8_t flags) { + vwd_.ls(&Serial, flags); +} +//------------------------------------------------------------------------------ +/** List the directory contents of the volume working directory to Serial. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ +void SdFat::ls(Print* pr, uint8_t flags) { + vwd_.ls(pr, flags); +} +#endif +//------------------------------------------------------------------------------ +/** Make a subdirectory in the volume working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::mkdir(const char* path, bool pFlag) { + SdBaseFile sub; + return sub.mkdir(&vwd_, path, pFlag); +} +//------------------------------------------------------------------------------ +/** Remove a file from the volume working directory. +* +* \param[in] path A path with a valid 8.3 DOS name for the file. +* +* \return The value one, true, is returned for success and +* the value zero, false, is returned for failure. +*/ +bool SdFat::remove(const char* path) { + return SdBaseFile::remove(&vwd_, path); +} +//------------------------------------------------------------------------------ +/** Rename a file or subdirectory. + * + * \param[in] oldPath Path name to the file or subdirectory to be renamed. + * + * \param[in] newPath New path name of the file or subdirectory. + * + * The \a newPath object must not exist before the rename call. + * + * The file to be renamed must not be open. The directory entry may be + * moved and file system corruption could occur if the file is accessed by + * a file object that was opened before the rename() call. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::rename(const char *oldPath, const char *newPath) { + SdBaseFile file; + if (!file.open(oldPath, O_READ)) return false; + return file.rename(&vwd_, newPath); +} +//------------------------------------------------------------------------------ +/** Remove a subdirectory from the volume's working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. + * + * The subdirectory file will be removed only if it is empty. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::rmdir(const char* path) { + SdBaseFile sub; + if (!sub.open(path, O_READ)) return false; + return sub.rmdir(); +} +//------------------------------------------------------------------------------ +/** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +bool SdFat::truncate(const char* path, uint32_t length) { + SdBaseFile file; + if (!file.open(path, O_WRITE)) return false; + return file.truncate(length); +} diff --git a/source-1.0L-F11/AVR/SdFat/SdFat.h b/source-1.0L-F11/AVR/SdFat/SdFat.h new file mode 100755 index 0000000..5a62b3f --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdFat.h @@ -0,0 +1,80 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdFat_h +#define SdFat_h +/** + * \file + * \brief SdFat class + */ +//#include +//#include +//#include +#include +//------------------------------------------------------------------------------ +/** SdFat version YYYYMMDD */ +#define SD_FAT_VERSION 20110902 +//------------------------------------------------------------------------------ +/** + * \class SdFat + * \brief Integration class for the %SdFat library. + */ +class SdFat { + public: + SdFat() {} + /** \return a pointer to the Sd2Card object. */ + Sd2Card* card() {return &card_;} + bool chdir(bool set_cwd = false); + bool chdir(const char* path, bool set_cwd = false); + void chvol(); +#if ARDUINO + void errorHalt(); + void errorHalt_P(PGM_P msg); + void errorHalt(char const *msg); + void errorPrint(); + void errorPrint_P(PGM_P msg); + void errorPrint(char const *msg); +#endif + bool exists(const char* name); + bool init(uint8_t sckRateID = SPI_FULL_SPEED); +#if ARDUINO + void initErrorHalt(); + void initErrorHalt(char const *msg); + void initErrorHalt_P(PGM_P msg); + void initErrorPrint(); + void initErrorPrint(char const *msg); + void initErrorPrint_P(PGM_P msg); + void ls(uint8_t flags = 0); + void ls(Print* pr, uint8_t flags = 0); +#endif + bool mkdir(const char* path, bool pFlag = true); + bool remove(const char* path); + bool rename(const char *oldPath, const char *newPath); + bool rmdir(const char* path); + bool truncate(const char* path, uint32_t length); + /** \return a pointer to the SdVolume object. */ + SdVolume* vol() {return &vol_;} + /** \return a pointer to the volume working directory. */ + SdBaseFile* vwd() {return &vwd_;} + private: + Sd2Card card_; + SdVolume vol_; + SdBaseFile vwd_; +}; +#endif // SdFat_h diff --git a/source-1.0L-F11/AVR/SdFat/SdFatConfig.h b/source-1.0L-F11/AVR/SdFat/SdFatConfig.h new file mode 100755 index 0000000..d09da96 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdFatConfig.h @@ -0,0 +1,108 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +/** + * \file + * \brief configuration definitions + */ +#ifndef SdFatConfig_h +#define SdFatConfig_h +#include +//------------------------------------------------------------------------------ +/** + * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. + * + * Using multiple cards costs 400 - 500 bytes of flash. + * + * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. + */ +#define USE_MULTIPLE_CARDS 0 +//------------------------------------------------------------------------------ +/** + * Call flush for endl if ENDL_CALLS_FLUSH is nonzero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for SD I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ +#define ENDL_CALLS_FLUSH 0 +//------------------------------------------------------------------------------ +/** + * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero + */ +#define ALLOW_DEPRECATED_FUNCTIONS 1 +//------------------------------------------------------------------------------ +/** + * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. + * FAT12 has not been well tested. + */ +#define FAT12_SUPPORT 0 +//------------------------------------------------------------------------------ +/** + * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64) + * or 6 (F_CPU/128). + */ +#define SPI_SD_INIT_RATE 5 +//------------------------------------------------------------------------------ +/** + * Set the SS pin high for hardware SPI. If SS is chip select for another SPI + * device this will disable that device during the SD init phase. + */ +#define SET_SPI_SS_HIGH 1 +//------------------------------------------------------------------------------ +/** + * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. + * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. + * + * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used + * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 + * but many SD cards will fail with GPS Shield V1.0. + */ +#define MEGA_SOFT_SPI 0 +//------------------------------------------------------------------------------ +/** + * Set USE_SOFTWARE_SPI nonzero to always use software SPI. + */ +#define USE_SOFTWARE_SPI 0 +// define software SPI pins so Mega can use unmodified 168/328 shields +/** Software SPI chip select pin for the SD */ +uint8_t const SOFT_SPI_CS_PIN = 10; +/** Software SPI Master Out Slave In pin */ +uint8_t const SOFT_SPI_MOSI_PIN = 11; +/** Software SPI Master In Slave Out pin */ +uint8_t const SOFT_SPI_MISO_PIN = 12; +/** Software SPI Clock pin */ +uint8_t const SOFT_SPI_SCK_PIN = 13; +//------------------------------------------------------------------------------ +/** + * The __cxa_pure_virtual function is an error handler that is invoked when + * a pure virtual function is called. + */ +#define USE_CXA_PURE_VIRTUAL 1 +#endif // SdFatConfig_h diff --git a/source-1.0L-F11/AVR/SdFat/SdFatStructs.h b/source-1.0L-F11/AVR/SdFat/SdFatStructs.h new file mode 100755 index 0000000..747c65f --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdFatStructs.h @@ -0,0 +1,604 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdFatStructs_h +#define SdFatStructs_h +/** + * \file + * \brief FAT file structures + */ +/* + * mostly from Microsoft document fatgen103.doc + * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + */ +//------------------------------------------------------------------------------ +/** Value for byte 510 of boot block or MBR */ +uint8_t const BOOTSIG0 = 0X55; +/** Value for byte 511 of boot block or MBR */ +uint8_t const BOOTSIG1 = 0XAA; +/** Value for bootSignature field int FAT/FAT32 boot sector */ +uint8_t const EXTENDED_BOOT_SIG = 0X29; +//------------------------------------------------------------------------------ +/** + * \struct partitionTable + * \brief MBR partition table entry + * + * A partition table entry for a MBR formatted storage device. + * The MBR partition table has four entries. + */ +struct partitionTable { + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0X00. Do not use for booting. + * 0X80 Active partition. + */ + uint8_t boot; + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t beginHead; + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned beginSector : 6; + /** High bits cylinder for first block in partition. */ + unsigned beginCylinderHigh : 2; + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t beginCylinderLow; + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ + uint8_t type; + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t endHead; + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned endSector : 6; + /** High bits of end cylinder */ + unsigned endCylinderHigh : 2; + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t endCylinderLow; + /** Logical block address of the first block in the partition. */ + uint32_t firstSector; + /** Length of the partition, in blocks. */ + uint32_t totalSectors; +}; +/** Type name for partitionTable */ +typedef struct partitionTable part_t; +//------------------------------------------------------------------------------ +/** + * \struct masterBootRecord + * + * \brief Master Boot Record + * + * The first block of a storage device that is formatted with a MBR. + */ +struct masterBootRecord { + /** Code Area for master boot program. */ + uint8_t codeArea[440]; + /** Optional Windows NT disk signature. May contain boot code. */ + uint32_t diskSignature; + /** Usually zero but may be more boot code. */ + uint16_t usuallyZero; + /** Partition tables. */ + part_t part[4]; + /** First MBR signature byte. Must be 0X55 */ + uint8_t mbrSig0; + /** Second MBR signature byte. Must be 0XAA */ + uint8_t mbrSig1; +}; +/** Type name for masterBootRecord */ +typedef struct masterBootRecord mbr_t; +//------------------------------------------------------------------------------ +/** + * \struct fat_boot + * + * \brief Boot sector for a FAT12/FAT16 volume. + * + */ +struct fat_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. The value of this field is always 1. + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be nonzero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be nonzero. + */ + uint32_t totalSectors32; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A field with a value of either FAT, FAT12 or FAT16, + * depending on the disk format. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[448]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +}; +/** Type name for FAT Boot Sector */ +typedef struct fat_boot fat_boot_t; +//------------------------------------------------------------------------------ +/** + * \struct fat32_boot + * + * \brief Boot sector for a FAT32 volume. + * + */ +struct fat32_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. Must not be zero + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. + */ + uint16_t rootDirEntryCount; + /** + * For FAT32 volumes, this field must be 0. + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * Contains the total number of sectors in the FAT32 volume. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced + * in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If nonzero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A text field with a value of FAT32. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[420]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +}; +/** Type name for FAT32 Boot Sector */ +typedef struct fat32_boot fat32_boot_t; +//------------------------------------------------------------------------------ +/** Lead signature for a FSINFO sector */ +uint32_t const FSINFO_LEAD_SIG = 0x41615252; +/** Struct signature for a FSINFO sector */ +uint32_t const FSINFO_STRUCT_SIG = 0x61417272; +/** + * \struct fat32_fsinfo + * + * \brief FSINFO sector for a FAT32 volume. + * + */ +struct fat32_fsinfo { + /** must be 0X52, 0X52, 0X61, 0X41 */ + uint32_t leadSignature; + /** must be zero */ + uint8_t reserved1[480]; + /** must be 0X72, 0X72, 0X41, 0X61 */ + uint32_t structSignature; + /** + * Contains the last known free cluster count on the volume. + * If the value is 0xFFFFFFFF, then the free count is unknown + * and must be computed. Any other value can be used, but is + * not necessarily correct. It should be range checked at least + * to make sure it is <= volume cluster count. + */ + uint32_t freeCount; + /** + * This is a hint for the FAT driver. It indicates the cluster + * number at which the driver should start looking for free clusters. + * If the value is 0xFFFFFFFF, then there is no hint and the driver + * should start looking at cluster 2. + */ + uint32_t nextFree; + /** must be zero */ + uint8_t reserved2[12]; + /** must be 0X00, 0X00, 0X55, 0XAA */ + uint8_t tailSignature[4]; +}; +/** Type name for FAT32 FSINFO Sector */ +typedef struct fat32_fsinfo fat32_fsinfo_t; +//------------------------------------------------------------------------------ +// End Of Chain values for FAT entries +/** FAT12 end of chain value used by Microsoft. */ +uint16_t const FAT12EOC = 0XFFF; +/** Minimum value for FAT12 EOC. Use to test for EOC. */ +uint16_t const FAT12EOC_MIN = 0XFF8; +/** FAT16 end of chain value used by Microsoft. */ +uint16_t const FAT16EOC = 0XFFFF; +/** Minimum value for FAT16 EOC. Use to test for EOC. */ +uint16_t const FAT16EOC_MIN = 0XFFF8; +/** FAT32 end of chain value used by Microsoft. */ +uint32_t const FAT32EOC = 0X0FFFFFFF; +/** Minimum value for FAT32 EOC. Use to test for EOC. */ +uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; +/** Mask a for FAT32 entry. Entries are 28 bits. */ +uint32_t const FAT32MASK = 0X0FFFFFFF; +//------------------------------------------------------------------------------ +/** + * \struct directoryEntry + * \brief FAT short directory entry + * + * Short means short 8.3 name, not the entry size. + * + * Date Format. A FAT directory entry date stamp is a 16-bit field that is + * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the + * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the + * 16-bit word): + * + * Bits 9-15: Count of years from 1980, valid value range 0-127 + * inclusive (1980-2107). + * + * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. + * + * Bits 0-4: Day of month, valid value range 1-31 inclusive. + * + * Time Format. A FAT directory entry time stamp is a 16-bit field that has + * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the + * 16-bit word, bit 15 is the MSB of the 16-bit word). + * + * Bits 11-15: Hours, valid value range 0-23 inclusive. + * + * Bits 5-10: Minutes, valid value range 0-59 inclusive. + * + * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). + * + * The valid time range is from Midnight 00:00:00 to 23:59:58. + */ +struct directoryEntry { + /** Short 8.3 name. + * + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ + uint8_t name[11]; + /** Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ + uint8_t attributes; + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ + uint8_t reservedNT; + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and its valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ + uint8_t creationTimeTenths; + /** Time file was created. */ + uint16_t creationTime; + /** Date file was created. */ + uint16_t creationDate; + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ + uint16_t lastAccessDate; + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ + uint16_t firstClusterHigh; + /** Time of last write. File creation is considered a write. */ + uint16_t lastWriteTime; + /** Date of last write. File creation is considered a write. */ + uint16_t lastWriteDate; + /** Low word of this entry's first cluster number. */ + uint16_t firstClusterLow; + /** 32-bit unsigned holding this file's size in bytes. */ + uint32_t fileSize; +}; +//------------------------------------------------------------------------------ +// Definitions for directory entries +// +/** Type name for directoryEntry */ +typedef struct directoryEntry dir_t; +/** escape for name[0] = 0XE5 */ +uint8_t const DIR_NAME_0XE5 = 0X05; +/** name[0] value for entry that is free after being "deleted" */ +uint8_t const DIR_NAME_DELETED = 0XE5; +/** name[0] value for entry that is free and no allocated entries follow */ +uint8_t const DIR_NAME_FREE = 0X00; +/** file is read-only */ +uint8_t const DIR_ATT_READ_ONLY = 0X01; +/** File should hidden in directory listings */ +uint8_t const DIR_ATT_HIDDEN = 0X02; +/** Entry is for a system file */ +uint8_t const DIR_ATT_SYSTEM = 0X04; +/** Directory entry contains the volume label */ +uint8_t const DIR_ATT_VOLUME_ID = 0X08; +/** Entry is for a directory */ +uint8_t const DIR_ATT_DIRECTORY = 0X10; +/** Old DOS archive bit for backup support */ +uint8_t const DIR_ATT_ARCHIVE = 0X20; +/** Test value for long name entry. Test is + (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ +uint8_t const DIR_ATT_LONG_NAME = 0X0F; +/** Test mask for long name entry */ +uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; +/** defined attribute bits */ +uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; +/** Directory entry is part of a long name + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for part of a long name else false. + */ +static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { + return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; +} +/** Mask for file/subdirectory tests */ +uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); +/** Directory entry is for a file + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file else false. + */ +static inline uint8_t DIR_IS_FILE(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; +} +/** Directory entry is for a subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a subdirectory else false. + */ +static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; +} +/** Directory entry is for a file or subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file or subdirectory else false. + */ +static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; +} +#endif // SdFatStructs_h diff --git a/source-1.0L-F11/AVR/SdFat/SdInfo.h b/source-1.0L-F11/AVR/SdFat/SdInfo.h new file mode 100755 index 0000000..2a58eb7 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdInfo.h @@ -0,0 +1,275 @@ +/* Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino Sd2Card Library. If not, see + * . + */ +#ifndef SdInfo_h +#define SdInfo_h +#include +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 3.01 +// May 18, 2010 +// +// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs +//------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +uint8_t const CMD0 = 0X00; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +uint8_t const CMD8 = 0X08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +uint8_t const CMD9 = 0X09; +/** SEND_CID - read the card identification information (CID register) */ +uint8_t const CMD10 = 0X0A; +/** STOP_TRANSMISSION - end multiple block read sequence */ +uint8_t const CMD12 = 0X0C; +/** SEND_STATUS - read the card status register */ +uint8_t const CMD13 = 0X0D; +/** READ_SINGLE_BLOCK - read a single data block from the card */ +uint8_t const CMD17 = 0X11; +/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */ +uint8_t const CMD18 = 0X12; +/** WRITE_BLOCK - write a single data block to the card */ +uint8_t const CMD24 = 0X18; +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +uint8_t const CMD25 = 0X19; +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +uint8_t const CMD32 = 0X20; +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +uint8_t const CMD33 = 0X21; +/** ERASE - erase all previously selected blocks */ +uint8_t const CMD38 = 0X26; +/** APP_CMD - escape for application specific command */ +uint8_t const CMD55 = 0X37; +/** READ_OCR - read the OCR register of a card */ +uint8_t const CMD58 = 0X3A; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +uint8_t const ACMD23 = 0X17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +uint8_t const ACMD41 = 0X29; +//------------------------------------------------------------------------------ +/** status for card in the ready state */ +uint8_t const R1_READY_STATE = 0X00; +/** status for card in the idle state */ +uint8_t const R1_IDLE_STATE = 0X01; +/** status bit for illegal command */ +uint8_t const R1_ILLEGAL_COMMAND = 0X04; +/** start data token for read or write single block*/ +uint8_t const DATA_START_BLOCK = 0XFE; +/** stop token for write multiple blocks*/ +uint8_t const STOP_TRAN_TOKEN = 0XFD; +/** start data token for write multiple blocks*/ +uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; +/** mask for data response tokens after a write block operation */ +uint8_t const DATA_RES_MASK = 0X1F; +/** write data accepted token */ +uint8_t const DATA_RES_ACCEPTED = 0X05; +//------------------------------------------------------------------------------ +/** Card IDentification (CID) register */ +typedef struct CID { + // byte 0 + /** Manufacturer ID */ + unsigned char mid; + // byte 1-2 + /** OEM/Application ID */ + char oid[2]; + // byte 3-7 + /** Product name */ + char pnm[5]; + // byte 8 + /** Product revision least significant digit */ + unsigned char prv_m : 4; + /** Product revision most significant digit */ + unsigned char prv_n : 4; + // byte 9-12 + /** Product serial number */ + uint32_t psn; + // byte 13 + /** Manufacturing date year low digit */ + unsigned char mdt_year_high : 4; + /** not used */ + unsigned char reserved : 4; + // byte 14 + /** Manufacturing date month */ + unsigned char mdt_month : 4; + /** Manufacturing date year low digit */ + unsigned char mdt_year_low :4; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** CRC7 checksum */ + unsigned char crc : 7; +}cid_t; +//------------------------------------------------------------------------------ +/** CSD for version 1.00 cards */ +typedef struct CSDV1 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + unsigned char taac; + // byte 2 + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + unsigned char c_size_high : 2; + unsigned char reserved2 : 2; + unsigned char dsr_imp : 1; + unsigned char read_blk_misalign :1; + unsigned char write_blk_misalign : 1; + unsigned char read_bl_partial : 1; + // byte 7 + unsigned char c_size_mid; + // byte 8 + unsigned char vdd_r_curr_max : 3; + unsigned char vdd_r_curr_min : 3; + unsigned char c_size_low :2; + // byte 9 + unsigned char c_size_mult_high : 2; + unsigned char vdd_w_cur_max : 3; + unsigned char vdd_w_curr_min : 3; + // byte 10 + unsigned char sector_size_high : 6; + unsigned char erase_blk_en : 1; + unsigned char c_size_mult_low : 1; + // byte 11 + unsigned char wp_grp_size : 7; + unsigned char sector_size_low : 1; + // byte 12 + unsigned char write_bl_len_high : 2; + unsigned char r2w_factor : 3; + unsigned char reserved3 : 2; + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved4 : 5; + unsigned char write_partial : 1; + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved5: 2; + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Indicates the file format on the card */ + unsigned char file_format_grp : 1; + // byte 15 + unsigned char always1 : 1; + unsigned char crc : 7; +}csd1_t; +//------------------------------------------------------------------------------ +/** CSD for version 2.00 cards */ +typedef struct CSDV2 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + /** fixed to 0X0E */ + unsigned char taac; + // byte 2 + /** fixed to 0 */ + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + /** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */ + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + /** not used */ + unsigned char reserved2 : 4; + unsigned char dsr_imp : 1; + /** fixed to 0 */ + unsigned char read_blk_misalign :1; + /** fixed to 0 */ + unsigned char write_blk_misalign : 1; + /** fixed to 0 - no partial read */ + unsigned char read_bl_partial : 1; + // byte 7 + /** not used */ + unsigned char reserved3 : 2; + /** high part of card size */ + unsigned char c_size_high : 6; + // byte 8 + /** middle part of card size */ + unsigned char c_size_mid; + // byte 9 + /** low part of card size */ + unsigned char c_size_low; + // byte 10 + /** sector size is fixed at 64 KB */ + unsigned char sector_size_high : 6; + /** fixed to 1 - erase single is supported */ + unsigned char erase_blk_en : 1; + /** not used */ + unsigned char reserved4 : 1; + // byte 11 + unsigned char wp_grp_size : 7; + /** sector size is fixed at 64 KB */ + unsigned char sector_size_low : 1; + // byte 12 + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_high : 2; + /** fixed value of 2 */ + unsigned char r2w_factor : 3; + /** not used */ + unsigned char reserved5 : 2; + /** fixed value of 0 - no write protect groups */ + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved6 : 5; + /** always zero - no partial block read*/ + unsigned char write_partial : 1; + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved7: 2; + /** Do not use always 0 */ + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Do not use always 0 */ + unsigned char file_format_grp : 1; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** checksum */ + unsigned char crc : 7; +}csd2_t; +//------------------------------------------------------------------------------ +/** union of old and new style CSD register */ +union csd_t { + csd1_t v1; + csd2_t v2; +}; +#endif // SdInfo_h diff --git a/source-1.0L-F11/AVR/SdFat/SdVolume.cpp b/source-1.0L-F11/AVR/SdFat/SdVolume.cpp new file mode 100755 index 0000000..1d45b9f --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdVolume.cpp @@ -0,0 +1,401 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#include +//------------------------------------------------------------------------------ +#if !USE_MULTIPLE_CARDS +// raw block cache +uint32_t SdVolume::cacheBlockNumber_; // current block number +cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card +Sd2Card* SdVolume::sdCard_; // pointer to SD card object +bool SdVolume::cacheDirty_; // cacheFlush() will write block if true +uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT +#endif // USE_MULTIPLE_CARDS +//------------------------------------------------------------------------------ +// find a contiguous group of clusters +bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { + // start of group + uint32_t bgnCluster; + // end of group + uint32_t endCluster; + // last cluster of FAT + uint32_t fatEnd = clusterCount_ + 1; + + // flag to save place to start next search + bool setStart; + + // set search start cluster + if (*curCluster) { + // try to make file contiguous + bgnCluster = *curCluster + 1; + + // don't save new start location + setStart = false; + } else { + // start at likely place for free cluster + bgnCluster = allocSearchStart_; + + // save next search start if one cluster + setStart = count == 1; + } + // end of group + endCluster = bgnCluster; + + // search the FAT for free clusters + for (uint32_t n = 0;; n++, endCluster++) { + // can't find space checked all clusters + if (n >= clusterCount_) goto fail; + + // past end - start from beginning of FAT + if (endCluster > fatEnd) { + bgnCluster = endCluster = 2; + } + uint32_t f; + if (!fatGet(endCluster, &f)) goto fail; + + if (f != 0) { + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; + } else if ((endCluster - bgnCluster + 1) == count) { + // done - found space + break; + } + } + // mark end of chain + if (!fatPutEOC(endCluster)) goto fail; + + // link clusters + while (endCluster > bgnCluster) { + if (!fatPut(endCluster - 1, endCluster)) goto fail; + endCluster--; + } + if (*curCluster != 0) { + // connect chains + if (!fatPut(*curCluster, bgnCluster)) goto fail; + } + // return first cluster number to caller + *curCluster = bgnCluster; + + // remember possible next free cluster + if (setStart) allocSearchStart_ = bgnCluster + 1; + + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheFlush() { + if (cacheDirty_) { + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { + goto fail; + } + // mirror FAT tables + if (cacheMirrorBlock_) { + if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { + goto fail; + } + cacheMirrorBlock_ = 0; + } + cacheDirty_ = 0; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) { + if (cacheBlockNumber_ != blockNumber) { + if (!cacheFlush()) goto fail; + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto fail; + cacheBlockNumber_ = blockNumber; + } + if (dirty) cacheDirty_ = true; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// return the size in bytes of a cluster chain +bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) { + uint32_t s = 0; + do { + if (!fatGet(cluster, &cluster)) goto fail; + s += 512UL << clusterSizeShift_; + } while (!isEOC(cluster)); + *size = s; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// Fetch a FAT entry +bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { + uint32_t lba; + if (cluster > (clusterCount_ + 1)) goto fail; + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail; + index &= 0X1FF; + uint16_t tmp = cacheBuffer_.data[index]; + index++; + if (index == 512) { + if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto fail; + index = 0; + } + tmp |= cacheBuffer_.data[index] << 8; + *value = cluster & 1 ? tmp >> 4 : tmp & 0XFFF; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } else { + goto fail; + } + if (lba != cacheBlockNumber_) { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail; + } + if (fatType_ == 16) { + *value = cacheBuffer_.fat16[cluster & 0XFF]; + } else { + *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// Store a FAT entry +bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { + uint32_t lba; + // error if reserved cluster + if (cluster < 2) goto fail; + + // error if not in FAT + if (cluster > (clusterCount_ + 1)) goto fail; + + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + index &= 0X1FF; + uint8_t tmp = value; + if (cluster & 1) { + tmp = (cacheBuffer_.data[index] & 0XF) | tmp << 4; + } + cacheBuffer_.data[index] = tmp; + index++; + if (index == 512) { + lba++; + index = 0; + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + } + tmp = value >> 4; + if (!(cluster & 1)) { + tmp = ((cacheBuffer_.data[index] & 0XF0)) | tmp >> 4; + } + cacheBuffer_.data[index] = tmp; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } else { + goto fail; + } + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; + // store entry + if (fatType_ == 16) { + cacheBuffer_.fat16[cluster & 0XFF] = value; + } else { + cacheBuffer_.fat32[cluster & 0X7F] = value; + } + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// free a cluster chain +bool SdVolume::freeChain(uint32_t cluster) { + uint32_t next; + + // clear free cluster location + allocSearchStart_ = 2; + + do { + if (!fatGet(cluster, &next)) goto fail; + + // free cluster + if (!fatPut(cluster, 0)) goto fail; + + cluster = next; + } while (!isEOC(cluster)); + + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Volume free space in clusters. + * + * \return Count of free clusters for success or -1 if an error occurs. + */ +int32_t SdVolume::freeClusterCount() { + uint32_t free = 0; + uint16_t n; + uint32_t todo = clusterCount_ + 2; + + if (fatType_ == 16) { + n = 256; + } else if (fatType_ == 32) { + n = 128; + } else { + // put FAT12 here + return -1; + } + + for (uint32_t lba = fatStartBlock_; todo; todo -= n, lba++) { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) return -1; + if (todo < n) n = todo; + if (fatType_ == 16) { + for (uint16_t i = 0; i < n; i++) { + if (cacheBuffer_.fat16[i] == 0) free++; + } + } else { + for (uint16_t i = 0; i < n; i++) { + if (cacheBuffer_.fat32[i] == 0) free++; + } + } + } + return free; +} +//------------------------------------------------------------------------------ +/** Initialize a FAT volume. + * + * \param[in] dev The SD card where the volume is located. + * + * \param[in] part The partition to be used. Legal values for \a part are + * 1-4 to use the corresponding partition on a device formatted with + * a MBR, Master Boot Record, or zero if the device is formatted as + * a super floppy with the FAT boot sector in block zero. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system in the specified partition or an I/O error. + */ +bool SdVolume::init(Sd2Card* dev, uint8_t part) { + uint32_t totalBlocks; + uint32_t volumeStartBlock = 0; + fat32_boot_t* fbs; + + sdCard_ = dev; + fatType_ = 0; + allocSearchStart_ = 2; + cacheDirty_ = 0; // cacheFlush() will write block if true + cacheMirrorBlock_ = 0; + cacheBlockNumber_ = 0XFFFFFFFF; + + // if part == 0 assume super floppy with FAT boot sector in block zero + // if part > 0 assume mbr volume with partition table + if (part) { + if (part > 4)goto fail; + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; + part_t* p = &cacheBuffer_.mbr.part[part-1]; + if ((p->boot & 0X7F) !=0 || + p->totalSectors < 100 || + p->firstSector == 0) { + // not a valid partition + goto fail; + } + volumeStartBlock = p->firstSector; + } + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; + fbs = &cacheBuffer_.fbs32; + if (fbs->bytesPerSector != 512 || + fbs->fatCount == 0 || + fbs->reservedSectorCount == 0 || + fbs->sectorsPerCluster == 0) { + // not valid FAT volume + goto fail; + } + fatCount_ = fbs->fatCount; + blocksPerCluster_ = fbs->sectorsPerCluster; + // determine shift that is same as multiply by blocksPerCluster_ + clusterSizeShift_ = 0; + while (blocksPerCluster_ != (1 << clusterSizeShift_)) { + // error if not power of 2 + if (clusterSizeShift_++ > 7) goto fail; + } + blocksPerFat_ = fbs->sectorsPerFat16 ? + fbs->sectorsPerFat16 : fbs->sectorsPerFat32; + + fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount; + + // count for FAT16 zero for FAT32 + rootDirEntryCount_ = fbs->rootDirEntryCount; + + // directory start for FAT16 dataStart for FAT32 + rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_; + + // data start for FAT16 and FAT32 + dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511)/512); + + // total blocks for FAT16 or FAT32 + totalBlocks = fbs->totalSectors16 ? + fbs->totalSectors16 : fbs->totalSectors32; + // total data blocks + clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); + + // divide by cluster size to get cluster count + clusterCount_ >>= clusterSizeShift_; + + // FAT type is determined by cluster count + if (clusterCount_ < 4085) { + fatType_ = 12; + if (!FAT12_SUPPORT) goto fail; + } else if (clusterCount_ < 65525) { + fatType_ = 16; + } else { + rootDirStart_ = fbs->fat32RootCluster; + fatType_ = 32; + } + return true; + + fail: + return false; +} diff --git a/source-1.0L-F11/AVR/SdFat/SdVolume.h b/source-1.0L-F11/AVR/SdFat/SdVolume.h new file mode 100755 index 0000000..f15cd6a --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/SdVolume.h @@ -0,0 +1,211 @@ +/* Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +#ifndef SdVolume_h +#define SdVolume_h +/** + * \file + * \brief SdVolume class + */ +#include +#include +#include + +//============================================================================== +// SdVolume class +/** + * \brief Cache for an SD data block + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached Master Boot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fat_boot_t fbs; + /** Used to access to a cached FAT32 boot sector. */ + fat32_boot_t fbs32; + /** Used to access to a cached FAT32 FSINFO sector. */ + fat32_fsinfo_t fsinfo; +}; +//------------------------------------------------------------------------------ +/** + * \class SdVolume + * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. + */ +class SdVolume { + public: + /** Create an instance of SdVolume */ + SdVolume() : fatType_(0) {} + /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + * recorder to do raw write to the SD card. Not for normal apps. + * \return A pointer to the cache buffer or zero if an error occurs. + */ + cache_t* cacheClear() { + if (!cacheFlush()) return 0; + cacheBlockNumber_ = 0XFFFFFFFF; + return &cacheBuffer_; + } + /** Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \param[in] dev The Sd2Card where the volume is located. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system or an I/O error. + */ + bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + bool init(Sd2Card* dev, uint8_t part); + + // inline functions that return volume info + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster() const {return blocksPerCluster_;} + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat() const {return blocksPerFat_;} + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount() const {return clusterCount_;} + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift() const {return clusterSizeShift_;} + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock() const {return dataStartBlock_;} + /** \return The number of FAT structures on the volume. */ + uint8_t fatCount() const {return fatCount_;} + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock() const {return fatStartBlock_;} + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType() const {return fatType_;} + int32_t freeClusterCount(); + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint32_t rootDirEntryCount() const {return rootDirEntryCount_;} + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart() const {return rootDirStart_;} + /** Sd2Card object for this volume + * \return pointer to Sd2Card object. + */ + Sd2Card* sdCard() {return sdCard_;} + /** Debug access to FAT table + * + * \param[in] n cluster number. + * \param[out] v value of entry + * \return true for success or false for failure + */ + bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} +//------------------------------------------------------------------------------ + private: + // Allow SdBaseFile access to SdVolume private data. + friend class SdBaseFile; + + // value for dirty argument in cacheRawBlock to indicate read from cache + static bool const CACHE_FOR_READ = false; + // value for dirty argument in cacheRawBlock to indicate write to cache + static bool const CACHE_FOR_WRITE = true; + +#if USE_MULTIPLE_CARDS + cache_t cacheBuffer_; // 512 byte cache for device blocks + uint32_t cacheBlockNumber_; // Logical number of block in the cache + Sd2Card* sdCard_; // Sd2Card object for cache + bool cacheDirty_; // cacheFlush() will write block if true + uint32_t cacheMirrorBlock_; // block number for mirror FAT +#else // USE_MULTIPLE_CARDS + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static Sd2Card* sdCard_; // Sd2Card object for cache + static bool cacheDirty_; // cacheFlush() will write block if true + static uint32_t cacheMirrorBlock_; // block number for mirror FAT +#endif // USE_MULTIPLE_CARDS + uint32_t allocSearchStart_; // start cluster for alloc search + uint8_t blocksPerCluster_; // cluster size in blocks + uint32_t blocksPerFat_; // FAT size in blocks + uint32_t clusterCount_; // clusters in one FAT + uint8_t clusterSizeShift_; // shift to convert cluster count to block count + uint32_t dataStartBlock_; // first data block number + uint8_t fatCount_; // number of FATs on volume + uint32_t fatStartBlock_; // start block for first FAT + uint8_t fatType_; // volume type (12, 16, OR 32) + uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir + uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 + //---------------------------------------------------------------------------- + bool allocContiguous(uint32_t count, uint32_t* curCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & (blocksPerCluster_ - 1);} + uint32_t clusterStartBlock(uint32_t cluster) const { + return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} + uint32_t blockNumber(uint32_t cluster, uint32_t position) const { + return clusterStartBlock(cluster) + blockOfCluster(position);} + cache_t *cache() {return &cacheBuffer_;} + uint32_t cacheBlockNumber() {return cacheBlockNumber_;} +#if USE_MULTIPLE_CARDS + bool cacheFlush(); + bool cacheRawBlock(uint32_t blockNumber, bool dirty); +#else // USE_MULTIPLE_CARDS + static bool cacheFlush(); + static bool cacheRawBlock(uint32_t blockNumber, bool dirty); +#endif // USE_MULTIPLE_CARDS + // used by SdBaseFile write to assign cache to SD location + void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) { + cacheDirty_ = dirty; + cacheBlockNumber_ = blockNumber; + } + void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;} + bool chainSize(uint32_t beginCluster, uint32_t* size); + bool fatGet(uint32_t cluster, uint32_t* value); + bool fatPut(uint32_t cluster, uint32_t value); + bool fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + bool freeChain(uint32_t cluster); + bool isEOC(uint32_t cluster) const { + if (FAT12_SUPPORT && fatType_ == 12) return cluster >= FAT12EOC_MIN; + if (fatType_ == 16) return cluster >= FAT16EOC_MIN; + return cluster >= FAT32EOC_MIN; + } + bool readBlock(uint32_t block, uint8_t* dst) { + return sdCard_->readBlock(block, dst);} + bool writeBlock(uint32_t block, const uint8_t* dst) { + return sdCard_->writeBlock(block, dst); + } +//------------------------------------------------------------------------------ + // Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + public: + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev); + * \param[in] dev The SD card where the volume is located. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev) {return init(&dev);} // NOLINT + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol); + * \param[in] dev The SD card where the volume is located. + * \param[in] part The partition to be used. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev, uint8_t part) { // NOLINT + return init(&dev, part); + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; +#endif // SdVolume diff --git a/source-1.0L-F11/AVR/SdFat/examples/AnalogLogger/AnalogLogger.pde b/source-1.0L-F11/AVR/SdFat/examples/AnalogLogger/AnalogLogger.pde new file mode 100755 index 0000000..39e761c --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/AnalogLogger/AnalogLogger.pde @@ -0,0 +1,166 @@ +// A simple data logger for the Arduino analog pins with optional DS1307 +// uses RTClib from https://github.com/adafruit/RTClib +#include +#include // define FreeRam() + +#define CHIP_SELECT SS_PIN // SD chip select pin +#define USE_DS1307 0 // set nonzero to use DS1307 RTC +#define LOG_INTERVAL 1000 // mills between entries +#define SENSOR_COUNT 3 // number of analog pins to log +#define ECHO_TO_SERIAL 1 // echo data to serial port if nonzero +#define WAIT_TO_START 1 // Wait for serial input in setup() +#define ADC_DELAY 10 // ADC delay for high impedence sensors + +// file system object +SdFat sd; + +// text file for logging +ofstream logfile; + +// Serial print stream +ArduinoOutStream cout(Serial); + +// buffer to format data - makes it eaiser to echo to Serial +char buf[80]; +//------------------------------------------------------------------------------ +#if SENSOR_COUNT > 6 +#error SENSOR_COUNT too large +#endif // SENSOR_COUNT +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt_P(PSTR(s)) +//------------------------------------------------------------------------------ +#if USE_DS1307 +// use RTClib from Adafruit +// https://github.com/adafruit/RTClib + +// The Arduino IDE has a bug that causes Wire and RTClib to be loaded even +// if USE_DS1307 is false. + +#error remove this line and uncomment the next two lines. +//#include +//#include +RTC_DS1307 RTC; // define the Real Time Clock object +//------------------------------------------------------------------------------ +// call back for file timestamps +void dateTime(uint16_t* date, uint16_t* time) { + DateTime now = RTC.now(); + + // return date using FAT_DATE macro to format fields + *date = FAT_DATE(now.year(), now.month(), now.day()); + + // return time using FAT_TIME macro to format fields + *time = FAT_TIME(now.hour(), now.minute(), now.second()); +} +//------------------------------------------------------------------------------ +// format date/time +ostream& operator << (ostream& os, DateTime& dt) { + os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ','; + os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute()); + os << ':' << setw(2) << int(dt.second()) << setfill(' '); + return os; +} +#endif // USE_DS1307 +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // pstr stores strings in flash to save RAM + cout << endl << pstr("FreeRam: ") << FreeRam() << endl; + +#if WAIT_TO_START + cout << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} +#endif // WAIT_TO_START + +#if USE_DS1307 + // connect to RTC + Wire.begin(); + if (!RTC.begin()) error("RTC failed"); + + // set date time callback function + SdFile::dateTimeCallback(dateTime); + DateTime now = RTC.now(); + cout << now << endl; +#endif // USE_DS1307 + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + // if SD chip select is not SS, the second argument to init is CS pin number + if (!sd.init(SPI_HALF_SPEED, CHIP_SELECT)) sd.initErrorHalt(); + + // create a new file in root, the current working directory + char name[] = "LOGGER00.CSV"; + + for (uint8_t i = 0; i < 100; i++) { + name[6] = i/10 + '0'; + name[7] = i%10 + '0'; + if (sd.exists(name)) continue; + logfile.open(name); + break; + } + if (!logfile.is_open()) error("file.open"); + + cout << pstr("Logging to: ") << name << endl; + + // format header in buffer + obufstream bout(buf, sizeof(buf)); + + bout << pstr("millis"); + +#if USE_DS1307 + bout << pstr(",date,time"); +#endif // USE_DS1307 + + for (uint8_t i = 0; i < SENSOR_COUNT; i++) { + bout << pstr(",sens") << int(i); + } + logfile << buf << endl; + +#if ECHO_TO_SERIAL + cout << buf << endl; +#endif // ECHO_TO_SERIAL +} +//------------------------------------------------------------------------------ +void loop() { + uint32_t m; + + // wait for time to be a multiple of interval + do { + m = millis(); + } while (m % LOG_INTERVAL); + + // use buffer stream to format line + obufstream bout(buf, sizeof(buf)); + + // start with time in millis + bout << m; + +#if USE_DS1307 + DateTime now = RTC.now(); + bout << ',' << now; +#endif // USE_DS1307 + + // read analog pins and format data + for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) { +#if ADC_DELAY + analogRead(ia); + delay(ADC_DELAY); +#endif // ADC_DELAY + bout << ',' << analogRead(ia); + } + bout << endl; + + // log data and flush to SD + logfile << buf << flush; + + // check for error + if (!logfile) error("write data failed"); + +#if ECHO_TO_SERIAL + cout << buf; +#endif // ECHO_TO_SERIAL + + // don't log two points in the same millis + if (m == millis()) delay(1); +} diff --git a/source-1.0L-F11/AVR/SdFat/examples/HelloWorld/HelloWorld.pde b/source-1.0L-F11/AVR/SdFat/examples/HelloWorld/HelloWorld.pde new file mode 100755 index 0000000..759146e --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/HelloWorld/HelloWorld.pde @@ -0,0 +1,11 @@ +#include + +// create a serial output stream +ArduinoOutStream cout(Serial); + +void setup() { + Serial.begin(9600); + cout << "Hello, World!\n"; +} + +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/OpenNext/OpenNext.pde b/source-1.0L-F11/AVR/SdFat/examples/OpenNext/OpenNext.pde new file mode 100755 index 0000000..6c36636 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/OpenNext/OpenNext.pde @@ -0,0 +1,35 @@ +/* + * Open all files in the root dir and print their filename + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system object +SdFat sd; + +SdFile file; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void setup() { + char name[13]; + + Serial.begin(9600); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // open next file in root. The volume working directory, vwd, is root + while (file.openNext(sd.vwd(), O_READ)) { + file.getFilename(name); + cout << name << endl; + file.close(); + } + cout << "Done" << endl; +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/QuickStart/QuickStart.pde b/source-1.0L-F11/AVR/SdFat/examples/QuickStart/QuickStart.pde new file mode 100755 index 0000000..ed89052 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/QuickStart/QuickStart.pde @@ -0,0 +1,134 @@ +// Quick hardware test +#include + +// Test with reduced SPI speed for breadboards. +// Change spiSpeed to SPI_FULL_SPEED for better performance +// Use SPI_QUARTER_SPEED for even slower SPI bus speed +const uint8_t spiSpeed = SPI_HALF_SPEED; +//------------------------------------------------------------------------------ +// Normally SdFat is used in applications in place +// of Sd2Card, SdVolume, and SdFile for root. +Sd2Card card; +SdVolume volume; +SdFile root; + +// Serial streams +ArduinoOutStream cout(Serial); + +// input buffer for line +char cinBuf[40]; +ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); + +// Change the value of chipSelect if your hardware does +// not use the default value, SS_PIN. Common values are: +// Arduino Ethernet shield: pin 4 +// Sparkfun SD shield: pin 8 +// Adafruit SD shields and modules: pin 10 +int chipSelect = SS_PIN; + +void cardOrSpeed() { + cout << pstr( + "Try another SD card or reduce the SPI bus speed.\n" + "The current SPI speed is: "); + uint8_t divisor = 1; + for (uint8_t i = 0; i < spiSpeed; i++) divisor *= 2; + cout << F_CPU * 0.5e-6 / divisor << pstr(" MHz\n"); + cout << pstr("Edit spiSpeed in this sketch to change it.\n"); +} + +void reformatMsg() { + cout << pstr("Try reformatting the card. For best results use\n"); + cout << pstr("the SdFormatter sketch in SdFat/examples or download\n"); + cout << pstr("and use SDFormatter from www.sdcard.org/consumer.\n"); +} + +void setup() { + Serial.begin(9600); + cout << pstr( + "SD chip select is the key hardware option.\n" + "Common values are:\n" + "Arduino Ethernet shield, pin 4\n" + "Sparkfun SD shield, pin 8\n" + "Adafruit SD shields and modules, pin 10\n" + "The default chip select pin number is pin "); + cout << int(SS_PIN) << endl; +} + +bool firstTry = true; +void loop() { + // read any existing Serial data + while (Serial.read() >= 0) {} + + if (!firstTry) cout << pstr("\nRestarting\n"); + firstTry = false; + + cout << pstr("\nEnter the chip select pin number: "); + cin.readline(); + if (cin >> chipSelect) { + cout << chipSelect << endl; + } else { + cout << pstr("\nInvalid pin number\n"); + return; + } + if (!card.init(spiSpeed, chipSelect)) { + cout << pstr( + "\nSD initialization failed.\n" + "Do not reformat the card!\n" + "Is the card correctly inserted?\n" + "Is chipSelect set to the correct value?\n" + "Is there a wiring/soldering problem?\n"); + cout << pstr("errorCode: ") << hex << showbase << int(card.errorCode()); + cout << pstr(", errorData: ") << int(card.errorData()); + cout << dec << noshowbase << endl; + return; + } + cout << pstr("\nCard successfully initialized.\n"); + cout << endl; + + uint32_t size = card.cardSize(); + if (size == 0) { + cout << pstr("Can't determine the card size.\n"); + cardOrSpeed(); + return; + } + uint32_t sizeMB = 0.000512 * size + 0.5; + cout << pstr("Card size: ") << sizeMB; + cout << pstr(" MB (MB = 1,000,000 bytes)\n"); + cout << endl; + + if (!volume.init(&card)) { + if (card.errorCode()) { + cout << pstr("Can't read the card.\n"); + cardOrSpeed(); + } else { + cout << pstr("Can't find a valid FAT16/FAT32 partition.\n"); + reformatMsg(); + } + return; + } + cout << pstr("Volume is FAT") << int(volume.fatType()); + cout << pstr(", Cluster size (bytes): ") << 512L * volume.blocksPerCluster(); + cout << endl << endl; + + root.close(); + if (!root.openRoot(&volume)) { + cout << pstr("Can't open root directory.\n"); + reformatMsg(); + return; + } + cout << pstr("Files found (name date time size):\n"); + root.ls(LS_R | LS_DATE | LS_SIZE); + + if ((sizeMB > 1100 && volume.blocksPerCluster() < 64) + || (sizeMB < 2200 && volume.fatType() == 32)) { + cout << pstr("\nThis card should be reformatted for best performance.\n"); + cout << pstr("Use a cluster size of 32 KB for cards larger than 1 GB.\n"); + cout << pstr("Only cards larger than 2 GB should be formatted FAT32.\n"); + reformatMsg(); + return; + } + // read any existing Serial data + while (Serial.read() >= 0) {} + cout << pstr("\nSuccess! Type any character to restart.\n"); + while (Serial.read() < 0) {} +} diff --git a/source-1.0L-F11/AVR/SdFat/examples/ReadWriteSdFat/ReadWriteSdFat.pde b/source-1.0L-F11/AVR/SdFat/examples/ReadWriteSdFat/ReadWriteSdFat.pde new file mode 100755 index 0000000..e303573 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/ReadWriteSdFat/ReadWriteSdFat.pde @@ -0,0 +1,64 @@ +// Ported to SdFat from the native Arduino SD library example by Bill Greiman +// On the Ethernet Shield, CS is pin 4. SdFat handles setting SS +const int chipSelect = 4; +/* + SD card read/write + + This example shows how to read and write data to and from an SD card file + The circuit: + * SD card attached to SPI bus as follows: + ** MOSI - pin 11 + ** MISO - pin 12 + ** CLK - pin 13 + ** CS - pin 4 + + created Nov 2010 + by David A. Mellis + updated 2 Dec 2010 + by Tom Igoe + modified by Bill Greiman 11 Apr 2011 + This example code is in the public domain. + + */ +#include +SdFat sd; +SdFile myFile; + +void setup() { + Serial.begin(9600); + + // Initialize SdFat or print a detailed error message and halt + // Use half speed like the native library. + // change to SPI_FULL_SPEED for more performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // open the file for write at end like the Native SD library + if (!myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) { + sd.errorHalt("opening test.txt for write failed"); + } + // if the file opened okay, write to it: + Serial.print("Writing to test.txt..."); + myFile.println("testing 1, 2, 3."); + + // close the file: + myFile.close(); + Serial.println("done."); + + // re-open the file for reading: + if (!myFile.open("test.txt", O_READ)) { + sd.errorHalt("opening test.txt for read failed"); + } + Serial.println("test.txt:"); + + // read from the file until there's nothing else in it: + int data; + while ((data = myFile.read()) > 0) Serial.write(data); + // close the file: + myFile.close(); +} + +void loop() { + // nothing happens after setup +} + + diff --git a/source-1.0L-F11/AVR/SdFat/examples/SD_Size/SD_Size.pde b/source-1.0L-F11/AVR/SdFat/examples/SD_Size/SD_Size.pde new file mode 100755 index 0000000..3865ff2 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/SD_Size/SD_Size.pde @@ -0,0 +1,23 @@ +/* + * Sketch to compare size of Arduino SD library with SdFat V2. + * See SdFatSize.pde for SdFat sketch. + */ +#include + +File file; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + if (!SD.begin()) { + Serial.println("begin failed"); + return; + } + file = SD.open("TEST_SD.TXT", FILE_WRITE); + + file.println("Hello"); + + file.close(); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/SdFatSize/SdFatSize.pde b/source-1.0L-F11/AVR/SdFat/examples/SdFatSize/SdFatSize.pde new file mode 100755 index 0000000..e5d1f90 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/SdFatSize/SdFatSize.pde @@ -0,0 +1,25 @@ +/* + * Sketch to compare size of SdFat V2 with Arduino SD library. + * See SD_Size.pde for Arduino SD sketch. + */ +#include + +SdFat sd; + +SdFile file; +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + if (!sd.init()) { + Serial.println("init failed"); + return; + } + file.open("SIZE_TST.TXT", O_RDWR | O_CREAT | O_AT_END); + + file.println("Hello"); + + file.close(); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/SdFormatter/SdFormatter.pde b/source-1.0L-F11/AVR/SdFat/examples/SdFormatter/SdFormatter.pde new file mode 100755 index 0000000..f01419d --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/SdFormatter/SdFormatter.pde @@ -0,0 +1,478 @@ +/* + * This sketch will format an SD or SDHC card. + * Warning all data will be deleted! + * + * For SD/SDHC cards larger than 64 MB this + * sketch attempts to match the format + * generated by SDFormatter available here: + * + * http://www.sdcard.org/consumers/formatter/ + * + * For smaller cards this sketch uses FAT16 + * and SDFormatter uses FAT12. + */ +// Print extra info for debug if DEBUG_PRINT is nonzero +#define DEBUG_PRINT 0 +#include +#if DEBUG_PRINT +#include +#endif // DEBUG_PRINT +// +// Change the value of chipSelect if your hardware does +// not use the default value, SS_PIN. Common values are: +// Arduino Ethernet shield: pin 4 +// Sparkfun SD shield: pin 8 +// Adafruit SD shields and modules: pin 10 +const uint8_t chipSelect = SS_PIN; + +// Change spiSpeed to SPI_FULL_SPEED for better performance +// Use SPI_QUARTER_SPEED for even slower SPI bus speed +const uint8_t spiSpeed = SPI_HALF_SPEED; + +// Serial output stream +ArduinoOutStream cout(Serial); + +Sd2Card card; +uint32_t cardSizeBlocks; +uint16_t cardCapacityMB; + +// cache for SD block +cache_t cache; + +// MBR information +uint8_t partType; +uint32_t relSector; +uint32_t partSize; + +// Fake disk geometry +uint8_t numberOfHeads; +uint8_t sectorsPerTrack; + +// FAT parameters +uint16_t reservedSectors; +uint8_t sectorsPerCluster; +uint32_t fatStart; +uint32_t fatSize; +uint32_t dataStart; + +// constants for file system structure +uint16_t const BU16 = 128; +uint16_t const BU32 = 8192; + +// strings needed in file system structures +char noName[] = "NO NAME "; +char fat16str[] = "FAT16 "; +char fat32str[] = "FAT32 "; +//------------------------------------------------------------------------------ +#define sdError(msg) sdError_P(PSTR(msg)) + +void sdError_P(const char* str) { + cout << pstr("error: "); + cout << pgm(str) << endl; + if (card.errorCode()) { + cout << pstr("SD error: ") << hex << int(card.errorCode()); + cout << ',' << int(card.errorData()) << dec << endl; + } + while (1); +} +//------------------------------------------------------------------------------ +#if DEBUG_PRINT +void debugPrint() { + cout << pstr("FreeRam: ") << FreeRam() << endl; + cout << pstr("partStart: ") << relSector << endl; + cout << pstr("partSize: ") << partSize << endl; + cout << pstr("reserved: ") << reservedSectors << endl; + cout << pstr("fatStart: ") << fatStart << endl; + cout << pstr("fatSize: ") << fatSize << endl; + cout << pstr("dataStart: ") << dataStart << endl; + cout << pstr("clusterCount: "); + cout << ((relSector + partSize - dataStart)/sectorsPerCluster) << endl; + cout << endl; + cout << pstr("Heads: ") << int(numberOfHeads) << endl; + cout << pstr("Sectors: ") << int(sectorsPerTrack) << endl; + cout << pstr("Cylinders: "); + cout << cardSizeBlocks/(numberOfHeads*sectorsPerTrack) << endl; +} +#endif // DEBUG_PRINT +//------------------------------------------------------------------------------ +// write cached block to the card +uint8_t writeCache(uint32_t lbn) { + return card.writeBlock(lbn, cache.data); +} +//------------------------------------------------------------------------------ +// initialize appropriate sizes for SD capacity +void initSizes() { + if (cardCapacityMB <= 6) { + sdError("Card is too small."); + } else if (cardCapacityMB <= 16) { + sectorsPerCluster = 2; + } else if (cardCapacityMB <= 32) { + sectorsPerCluster = 4; + } else if (cardCapacityMB <= 64) { + sectorsPerCluster = 8; + } else if (cardCapacityMB <= 128) { + sectorsPerCluster = 16; + } else if (cardCapacityMB <= 1024) { + sectorsPerCluster = 32; + } else { + sectorsPerCluster = 64; + } + + cout << pstr("Blocks/Cluster: ") << int(sectorsPerCluster) << endl; + // set fake disk geometry + sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63; + + if (cardCapacityMB <= 16) { + numberOfHeads = 2; + } else if (cardCapacityMB <= 32) { + numberOfHeads = 4; + } else if (cardCapacityMB <= 128) { + numberOfHeads = 8; + } else if (cardCapacityMB <= 504) { + numberOfHeads = 16; + } else if (cardCapacityMB <= 1008) { + numberOfHeads = 32; + } else if (cardCapacityMB <= 2016) { + numberOfHeads = 64; + } else if (cardCapacityMB <= 4032) { + numberOfHeads = 128; + } else { + numberOfHeads = 255; + } +} +//------------------------------------------------------------------------------ +// zero cache and optionally set the sector signature +void clearCache(uint8_t addSig) { + memset(&cache, 0, sizeof(cache)); + if (addSig) { + cache.mbr.mbrSig0 = BOOTSIG0; + cache.mbr.mbrSig1 = BOOTSIG1; + } +} +//------------------------------------------------------------------------------ +// zero FAT and root dir area on SD +void clearFatDir(uint32_t bgn, uint32_t count) { + clearCache(false); + if (!card.writeStart(bgn, count)) { + sdError("Clear FAT/DIR writeStart failed"); + } + for (uint32_t i = 0; i < count; i++) { + if ((i & 0XFF) == 0) cout << '.'; + if (!card.writeData(cache.data)) { + sdError("Clear FAT/DIR writeData failed"); + } + } + if (!card.writeStop()) { + sdError("Clear FAT/DIR writeStop failed"); + } + cout << endl; +} +//------------------------------------------------------------------------------ +// return cylinder number for a logical block number +uint16_t lbnToCylinder(uint32_t lbn) { + return lbn / (numberOfHeads * sectorsPerTrack); +} +//------------------------------------------------------------------------------ +// return head number for a logical block number +uint8_t lbnToHead(uint32_t lbn) { + return (lbn % (numberOfHeads * sectorsPerTrack)) / sectorsPerTrack; +} +//------------------------------------------------------------------------------ +// return sector number for a logical block number +uint8_t lbnToSector(uint32_t lbn) { + return (lbn % sectorsPerTrack) + 1; +} +//------------------------------------------------------------------------------ +// format and write the Master Boot Record +void writeMbr() { + clearCache(true); + part_t* p = cache.mbr.part; + p->boot = 0; + uint16_t c = lbnToCylinder(relSector); + if (c > 1023) sdError("MBR CHS"); + p->beginCylinderHigh = c >> 8; + p->beginCylinderLow = c & 0XFF; + p->beginHead = lbnToHead(relSector); + p->beginSector = lbnToSector(relSector); + p->type = partType; + uint32_t endLbn = relSector + partSize - 1; + c = lbnToCylinder(endLbn); + if (c <= 1023) { + p->endCylinderHigh = c >> 8; + p->endCylinderLow = c & 0XFF; + p->endHead = lbnToHead(endLbn); + p->endSector = lbnToSector(endLbn); + } else { + // Too big flag, c = 1023, h = 254, s = 63 + p->endCylinderHigh = 3; + p->endCylinderLow = 255; + p->endHead = 254; + p->endSector = 63; + } + p->firstSector = relSector; + p->totalSectors = partSize; + if (!writeCache(0)) sdError("write MBR"); +} +//------------------------------------------------------------------------------ +// generate serial number from card size and micros since boot +uint32_t volSerialNumber() { + return (cardSizeBlocks << 8) + micros(); +} +//------------------------------------------------------------------------------ +// format the SD as FAT16 +void makeFat16() { + uint32_t nc; + for (dataStart = 2 * BU16;; dataStart += BU16) { + nc = (cardSizeBlocks - dataStart)/sectorsPerCluster; + fatSize = (nc + 2 + 255)/256; + uint32_t r = BU16 + 1 + 2 * fatSize + 32; + if (dataStart < r) continue; + relSector = dataStart - r + BU16; + break; + } + // check valid cluster count for FAT16 volume + if (nc < 4085 || nc >= 65525) sdError("Bad cluster count"); + reservedSectors = 1; + fatStart = relSector + reservedSectors; + partSize = nc * sectorsPerCluster + 2 * fatSize + reservedSectors + 32; + if (partSize < 32680) { + partType = 0X01; + } else if (partSize < 65536) { + partType = 0X04; + } else { + partType = 0X06; + } + // write MBR + writeMbr(); + clearCache(true); + fat_boot_t* pb = &cache.fbs; + pb->jump[0] = 0XEB; + pb->jump[1] = 0X00; + pb->jump[2] = 0X90; + for (uint8_t i = 0; i < sizeof(pb->oemId); i++) { + pb->oemId[i] = ' '; + } + pb->bytesPerSector = 512; + pb->sectorsPerCluster = sectorsPerCluster; + pb->reservedSectorCount = reservedSectors; + pb->fatCount = 2; + pb->rootDirEntryCount = 512; + pb->mediaType = 0XF8; + pb->sectorsPerFat16 = fatSize; + pb->sectorsPerTrack = sectorsPerTrack; + pb->headCount = numberOfHeads; + pb->hidddenSectors = relSector; + pb->totalSectors32 = partSize; + pb->driveNumber = 0X80; + pb->bootSignature = EXTENDED_BOOT_SIG; + pb->volumeSerialNumber = volSerialNumber(); + memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel)); + memcpy(pb->fileSystemType, fat16str, sizeof(pb->fileSystemType)); + // write partition boot sector + if (!writeCache(relSector)) { + sdError("FAT16 write PBS failed"); + } + // clear FAT and root directory + clearFatDir(fatStart, dataStart - fatStart); + clearCache(false); + cache.fat16[0] = 0XFFF8; + cache.fat16[1] = 0XFFFF; + // write first block of FAT and backup for reserved clusters + if (!writeCache(fatStart) + || !writeCache(fatStart + fatSize)) { + sdError("FAT16 reserve failed"); + } +} +//------------------------------------------------------------------------------ +// format the SD as FAT32 +void makeFat32() { + uint32_t nc; + relSector = BU32; + for (dataStart = 2 * BU32;; dataStart += BU32) { + nc = (cardSizeBlocks - dataStart)/sectorsPerCluster; + fatSize = (nc + 2 + 127)/128; + uint32_t r = relSector + 9 + 2 * fatSize; + if (dataStart >= r) break; + } + // error if too few clusters in FAT32 volume + if (nc < 65525) sdError("Bad cluster count"); + reservedSectors = dataStart - relSector - 2 * fatSize; + fatStart = relSector + reservedSectors; + partSize = nc * sectorsPerCluster + dataStart - relSector; + // type depends on address of end sector + // max CHS has lbn = 16450560 = 1024*255*63 + if ((relSector + partSize) <= 16450560) { + // FAT32 + partType = 0X0B; + } else { + // FAT32 with INT 13 + partType = 0X0C; + } + writeMbr(); + clearCache(true); + + fat32_boot_t* pb = &cache.fbs32; + pb->jump[0] = 0XEB; + pb->jump[1] = 0X00; + pb->jump[2] = 0X90; + for (uint8_t i = 0; i < sizeof(pb->oemId); i++) { + pb->oemId[i] = ' '; + } + pb->bytesPerSector = 512; + pb->sectorsPerCluster = sectorsPerCluster; + pb->reservedSectorCount = reservedSectors; + pb->fatCount = 2; + pb->mediaType = 0XF8; + pb->sectorsPerTrack = sectorsPerTrack; + pb->headCount = numberOfHeads; + pb->hidddenSectors = relSector; + pb->totalSectors32 = partSize; + pb->sectorsPerFat32 = fatSize; + pb->fat32RootCluster = 2; + pb->fat32FSInfo = 1; + pb->fat32BackBootBlock = 6; + pb->driveNumber = 0X80; + pb->bootSignature = EXTENDED_BOOT_SIG; + pb->volumeSerialNumber = volSerialNumber(); + memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel)); + memcpy(pb->fileSystemType, fat32str, sizeof(pb->fileSystemType)); + // write partition boot sector and backup + if (!writeCache(relSector) + || !writeCache(relSector + 6)) { + sdError("FAT32 write PBS failed"); + } + clearCache(true); + // write extra boot area and backup + if (!writeCache(relSector + 2) + || !writeCache(relSector + 8)) { + sdError("FAT32 PBS ext failed"); + } + fat32_fsinfo_t* pf = &cache.fsinfo; + pf->leadSignature = FSINFO_LEAD_SIG; + pf->structSignature = FSINFO_STRUCT_SIG; + pf->freeCount = 0XFFFFFFFF; + pf->nextFree = 0XFFFFFFFF; + // write FSINFO sector and backup + if (!writeCache(relSector + 1) + || !writeCache(relSector + 7)) { + sdError("FAT32 FSINFO failed"); + } + clearFatDir(fatStart, 2 * fatSize + sectorsPerCluster); + clearCache(false); + cache.fat32[0] = 0x0FFFFFF8; + cache.fat32[1] = 0x0FFFFFFF; + cache.fat32[2] = 0x0FFFFFFF; + // write first block of FAT and backup for reserved clusters + if (!writeCache(fatStart) + || !writeCache(fatStart + fatSize)) { + sdError("FAT32 reserve failed"); + } +} +//------------------------------------------------------------------------------ +// flash erase all data +uint32_t const ERASE_SIZE = 262144L; +void eraseCard() { + cout << endl << pstr("Erasing\n"); + uint32_t firstBlock = 0; + uint32_t lastBlock; + uint16_t n = 0; + + do { + lastBlock = firstBlock + ERASE_SIZE - 1; + if (lastBlock >= cardSizeBlocks) lastBlock = cardSizeBlocks - 1; + if (!card.erase(firstBlock, lastBlock)) sdError("erase failed"); + cout << '.'; + if ((n++)%32 == 31) cout << endl; + firstBlock += ERASE_SIZE; + } while (firstBlock < cardSizeBlocks); + cout << endl; + + if (!card.readBlock(0, cache.data)) sdError("readBlock"); + cout << hex << showbase << setfill('0') << internal; + cout << pstr("All data set to ") << setw(4) << int(cache.data[0]) << endl; + cout << dec << noshowbase << setfill(' ') << right; + cout << pstr("Erase done\n"); +} +//------------------------------------------------------------------------------ +void formatCard() { + cout << endl; + cout << pstr("Formatting\n"); + initSizes(); + if (card.type() != SD_CARD_TYPE_SDHC) { + cout << pstr("FAT16\n"); + makeFat16(); + } else { + cout << pstr("FAT32\n"); + makeFat32(); + } +#if DEBUG_PRINT + debugPrint(); +#endif // DEBUG_PRINT + cout << pstr("Format done\n"); +} +//------------------------------------------------------------------------------ +void setup() { + char c; + Serial.begin(9600); + cout << pstr( + "This sketch can erase and/or format SD/SDHC cards.\n" + "\n" + "Erase uses the card's fast flash erase command.\n" + "Flash erase sets all data to 0X00 for most cards\n" + "and 0XFF for a few vendor's cards.\n" + "\n" + "Cards larger than 2 GB will be formatted FAT32 and\n" + "smaller cards will be formatted FAT16.\n" + "\n" + "Warning, all data on the card will be erased.\n" + "Enter 'Y' to continue: "); + while (!Serial.available()) {} + c = Serial.read(); + cout << c << endl; + if (c != 'Y') { + cout << pstr("Quiting, you did not enter 'Y'.\n"); + return; + } + // read any existing Serial data + while (Serial.read() >= 0) {} + + cout << pstr( + "\n" + "Options are:\n" + "E - erase the card and skip formatting.\n" + "F - erase and then format the card. (recommended)\n" + "Q - quick format the card without erase.\n" + "\n" + "Enter option: "); + + while (!Serial.available()) {} + c = Serial.read(); + cout << c << endl; + if (!strchr("EFQ", c)) { + cout << pstr("Quiting, invalid option entered.") << endl; + return; + } + + if (!card.init(spiSpeed, chipSelect)) { + cout << pstr( + "\nSD initialization failure!\n" + "Is the SD card inserted correctly?\n" + "Is chip select correct at the top of this sketch?\n"); + sdError("card.init failed"); + } + cardSizeBlocks = card.cardSize(); + if (cardSizeBlocks == 0) sdError("cardSize"); + cardCapacityMB = (cardSizeBlocks + 2047)/2048; + + cout << pstr("Card Size: ") << cardCapacityMB; + cout << pstr(" MB, (MB = 1,048,576 bytes)") << endl; + + if (c == 'E' || c == 'F') { + eraseCard(); + } + if (c == 'F' || c == 'Q') { + formatCard(); + } +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/SdInfo/SdInfo.pde b/source-1.0L-F11/AVR/SdFat/examples/SdInfo/SdInfo.pde new file mode 100755 index 0000000..c36393e --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/SdInfo/SdInfo.pde @@ -0,0 +1,174 @@ +/* + * This sketch attempts to initialize an SD card and analyze its structure. + */ +#include +/* + * SD chip select pin. Common values are: + * + * Arduino Ethernet shield, pin 4. + * SparkFun SD shield, pin 8. + * Adafruit SD shields and modules, pin 10. + * Default SD chip select is the SPI SS pin. + */ +const uint8_t SdChipSelect = SS_PIN; + +Sd2Card card; +SdVolume vol; + +// serial output steam +ArduinoOutStream cout(Serial); + +// global for card erase size +uint32_t eraseSize; +//------------------------------------------------------------------------------ +// store error strings in flash +#define sdErrorMsg(msg) sdErrorMsg_P(PSTR(msg)); +void sdErrorMsg_P(const char* str) { + cout << pgm(str) << endl; + if (card.errorCode()) { + cout << pstr("SD errorCode: "); + cout << hex << int(card.errorCode()) << endl; + cout << pstr("SD errorData: "); + cout << int(card.errorData()) << dec << endl; + } +} +//------------------------------------------------------------------------------ +uint8_t cidDmp() { + cid_t cid; + if (!card.readCID(&cid)) { + sdErrorMsg("readCID failed"); + return false; + } + cout << pstr("\nManufacturer ID: "); + cout << hex << int(cid.mid) << dec << endl; + cout << pstr("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl; + cout << pstr("Product: "); + for (uint8_t i = 0; i < 5; i++) { + cout << cid.pnm[i]; + } + cout << pstr("\nVersion: "); + cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl; + cout << pstr("Serial number: ") << cid.psn << endl; + cout << pstr("Manufacturing date: "); + cout << int(cid.mdt_month) << '/'; + cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl; + cout << endl; + return true; +} +//------------------------------------------------------------------------------ +uint8_t csdDmp() { + csd_t csd; + uint8_t eraseSingleBlock; + uint32_t cardSize = card.cardSize(); + if (cardSize == 0 || !card.readCSD(&csd)) { + sdErrorMsg("readCSD failed"); + return false; + } + if (csd.v1.csd_ver == 0) { + eraseSingleBlock = csd.v1.erase_blk_en; + eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + } else if (csd.v2.csd_ver == 1) { + eraseSingleBlock = csd.v2.erase_blk_en; + eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low; + } else { + cout << pstr("csd version error\n"); + return false; + } + eraseSize++; + cout << pstr("cardSize: ") << cardSize << pstr(" (512 byte blocks)\n"); + cout << pstr("flashEraseSize: ") << int(eraseSize) << pstr(" blocks\n"); + cout << pstr("eraseSingleBlock: "); + if (eraseSingleBlock) { + cout << pstr("true\n"); + } else { + cout << pstr("false\n"); + } + return true; +} +//------------------------------------------------------------------------------ +// print partition table +uint8_t partDmp() { + cache_t *p = vol.cacheClear(); + if (!card.readBlock(0, p->data)) { + sdErrorMsg("read MBR failed"); + return false; + } + cout << pstr("\nSD Partition Table\n"); + cout << pstr("part,boot,type,start,length\n"); + for (uint8_t ip = 1; ip < 5; ip++) { + part_t *pt = &p->mbr.part[ip - 1]; + cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type); + cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl; + } + return true; +} +//------------------------------------------------------------------------------ +void volDmp() { + cout << pstr("\nVolume is FAT") << int(vol.fatType()) << endl; + cout << pstr("blocksPerCluster: ") << int(vol.blocksPerCluster()) << endl; + cout << pstr("clusterCount: ") << vol.clusterCount() << endl; + cout << pstr("freeClusters: ") << vol.freeClusterCount() << endl; + cout << pstr("fatStartBlock: ") << vol.fatStartBlock() << endl; + cout << pstr("fatCount: ") << int(vol.fatCount()) << endl; + cout << pstr("blocksPerFat: ") << vol.blocksPerFat() << endl; + cout << pstr("rootDirStart: ") << vol.rootDirStart() << endl; + cout << pstr("dataStartBlock: ") << vol.dataStartBlock() << endl; + if (vol.dataStartBlock() % eraseSize) { + cout << pstr("Data area is not aligned on flash erase boundaries!\n"); + cout << pstr("Download and use formatter from www.sdcard.org/consumer!\n"); + } +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // use uppercase in hex and use 0X base prefix + cout << uppercase << showbase << endl; + + // pstr stores strings in flash to save RAM + cout << pstr("SdFat version: ") << SD_FAT_VERSION << endl; +} +//------------------------------------------------------------------------------ +void loop() { + // read any existing Serial data + while (Serial.read() >= 0) {} + + // pstr stores strings in flash to save RAM + cout << pstr("\ntype any character to start\n"); + while (Serial.read() < 0) {} + + uint32_t t = millis(); + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!card.init(SPI_HALF_SPEED, SdChipSelect)) { + sdErrorMsg("\ncard.init failed"); + return; + } + t = millis() - t; + cout << pstr("\ninit time: ") << t << " ms" << endl; + cout << pstr("\nCard type: "); + switch (card.type()) { + case SD_CARD_TYPE_SD1: + cout << pstr("SD1\n"); + break; + + case SD_CARD_TYPE_SD2: + cout << pstr("SD2\n"); + break; + + case SD_CARD_TYPE_SDHC: + cout << pstr("SDHC\n"); + break; + + default: + cout << pstr("Unknown\n"); + } + if (!cidDmp()) return; + if (!csdDmp()) return; + if (!partDmp()) return; + if (!vol.init(&card)) { + sdErrorMsg("\nvol.init failed"); + return; + } + volDmp(); +} diff --git a/source-1.0L-F11/AVR/SdFat/examples/TwoCards/TwoCards.pde b/source-1.0L-F11/AVR/SdFat/examples/TwoCards/TwoCards.pde new file mode 100755 index 0000000..5ac4649 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/TwoCards/TwoCards.pde @@ -0,0 +1,137 @@ +/* + * Example use of two SD cards. + */ +#include +#include +#if !USE_MULTIPLE_CARDS +#error You must set USE_MULTIPLE_CARDS nonzero in SdFatConfig.h +#endif + +SdFat sd1; +const uint8_t SD1_CS = 10; // chip select for sd1 + +SdFat sd2; +const uint8_t SD2_CS = 9; // chip select for sd2 + +const uint8_t BUF_DIM = 100; +uint8_t buf[BUF_DIM]; + +const uint32_t FILE_SIZE = 1000000; +const uint16_t NWRITE = FILE_SIZE/BUF_DIM; +//------------------------------------------------------------------------------ +// print error msg, any SD error codes, and halt. +// store messages in flash +#define errorExit(msg) errorHalt_P(PSTR(msg)) +#define initError(msg) initErrorHalt_P(PSTR(msg)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + PgmPrint("FreeRam: "); + Serial.println(FreeRam()); + + // fill buffer with known data + for (int i = 0; i < sizeof(buf); i++) buf[i] = i; + + PgmPrintln("type any character to start"); + while (Serial.read() < 0) {} + + // disable sd2 while initializing sd1 + pinMode(SD2_CS, OUTPUT); + digitalWrite(SD2_CS, HIGH); + + // initialize the first card + if (!sd1.init(SPI_FULL_SPEED, SD1_CS)) { + sd1.initError("sd1:"); + } + // create DIR1 on sd1 if it does not exist + if (!sd1.exists("/DIR1")) { + if (!sd1.mkdir("/DIR1")) sd1.errorExit("sd1.mkdir"); + } + // initialize the second card + if (!sd2.init(SPI_FULL_SPEED, SD2_CS)) { + sd2.initError("sd2:"); + } + // create DIR2 on sd2 if it does not exist + if (!sd2.exists("/DIR2")) { + if (!sd2.mkdir("/DIR2")) sd2.errorExit("sd2.mkdir"); + } + // list root directory on both cards + PgmPrintln("------sd1 root-------"); + sd1.ls(); + PgmPrintln("------sd2 root-------"); + sd2.ls(); + + // make /DIR1 the default directory for sd1 + if (!sd1.chdir("/DIR1")) sd1.errorExit("sd1.chdir"); + + // make /DIR2 the default directory for sd2 + if (!sd2.chdir("/DIR2")) sd2.errorExit("sd2.chdir"); + + // list current directory on both cards + PgmPrintln("------sd1 DIR1-------"); + sd1.ls(); + PgmPrintln("------sd2 DIR2-------"); + sd2.ls(); + PgmPrintln("---------------------"); + + // remove RENAME.BIN from /DIR2 directory of sd2 + if (sd2.exists("RENAME.BIN")) { + if (!sd2.remove("RENAME.BIN")) { + sd2.errorExit("remove RENAME.BIN"); + } + } + // set the current working directory for open() to sd1 + sd1.chvol(); + + // create or open /DIR1/TEST.BIN and truncate it to zero length + SdFile file1; + if (!file1.open("TEST.BIN", O_RDWR | O_CREAT | O_TRUNC)) { + sd1.errorExit("file1"); + } + PgmPrintln("Writing TEST.BIN to sd1"); + + // write data to /DIR1/TEST.BIN on sd1 + for (int i = 0; i < NWRITE; i++) { + if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { + sd1.errorExit("sd1.write"); + } + } + // set the current working directory for open() to sd2 + sd2.chvol(); + + // create or open /DIR2/COPY.BIN and truncate it to zero length + SdFile file2; + if (!file2.open("COPY.BIN", O_WRITE | O_CREAT | O_TRUNC)) { + sd2.errorExit("file2"); + } + PgmPrintln("Copying TEST.BIN to COPY.BIN"); + + // copy file1 to file2 + file1.rewind(); + uint32_t t = millis(); + + while (1) { + int n = file1.read(buf, sizeof(buf)); + if (n < 0) sd1.errorExit("read1"); + if (n == 0) break; + if (file2.write(buf, n) != n) sd2.errorExit("write2"); + } + t = millis() - t; + PgmPrint("File size: "); + Serial.println(file2.fileSize()); + PgmPrint("Copy time: "); + Serial.print(t); + PgmPrintln(" millis"); + + // close TEST.BIN + file1.close(); + + // rename the copy + file2.close(); + if (!sd2.rename("COPY.BIN", "RENAME.BIN")) { + sd2.errorExit("sd2.rename"); + } + PgmPrintln("Done"); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/append/append.pde b/source-1.0L-F11/AVR/SdFat/examples/append/append.pde new file mode 100755 index 0000000..3fb3e8e --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/append/append.pde @@ -0,0 +1,61 @@ +/* + * Append Example + * + * This sketch shows how to use open for append. + * The sketch will append 100 line each time it opens the file. + * The sketch will open and close the file 100 times. + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system object +SdFat sd; + +// create Serial stream +ArduinoOutStream cout(Serial); + +// store error strings in flash to save RAM +#define error(s) sd.errorHalt_P(PSTR(s)) +//------------------------------------------------------------------------------ +void setup() { + // filename for this example + char name[] = "APPEND.TXT"; + + Serial.begin(9600); + + // pstr() stores strings in flash to save RAM + cout << endl << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + cout << pstr("Appending to: ") << name; + + for (uint8_t i = 0; i < 100; i++) { + // open stream for append + ofstream sdout(name, ios::out | ios::app); + if (!sdout) error("open failed"); + + // append 100 lines to the file + for (uint8_t j = 0; j < 100; j++) { + // use int() so byte will print as decimal number + sdout << "line " << int(j) << " of pass " << int(i); + sdout << " millis = " << millis() << endl; + } + // close the stream + sdout.close(); + + if (!sdout) error("append data failed"); + + // output progress indicator + if (i % 25 == 0) cout << endl; + cout << '.'; + } + cout << endl << "Done" << endl; +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/average/average.pde b/source-1.0L-F11/AVR/SdFat/examples/average/average.pde new file mode 100755 index 0000000..2e18454 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/average/average.pde @@ -0,0 +1,68 @@ +/* + * Calculate the sum and average of a list of floating point numbers + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// object for the SD file system +SdFat sd; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void writeTestFile() { + // open the output file + ofstream sdout("AVG_TEST.TXT"); + + // write a series of float numbers + for (int16_t i = -1001; i < 2000; i += 13) { + sdout << 0.1 * i << endl; + } + if (!sdout) sd.errorHalt("sdout failed"); + + // file will be closed by destructor when sdout goes out of scope +} +//------------------------------------------------------------------------------ +void calcAverage() { + uint16_t n = 0; // count of input numbers + double num; // current input number + double sum = 0; // sum of input numbers + + // open the input file + ifstream sdin("AVG_TEST.TXT"); + + // check for an open failure + if (!sdin) sd.errorHalt("sdin failed"); + + // read and sum the numbers + while (sdin >> num) { + n++; + sum += num; + } + + // print the results + cout << "sum of " << n << " numbers = " << sum << endl; + cout << "average = " << sum/n << endl; +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // pstr stores strings in flash to save RAM + cout << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // write the test file + writeTestFile(); + + // read the test file and calculate the average + calcAverage(); +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/bench/bench.pde b/source-1.0L-F11/AVR/SdFat/examples/bench/bench.pde new file mode 100755 index 0000000..d39395a --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/bench/bench.pde @@ -0,0 +1,103 @@ +/* + * This sketch is a simple binary write/read benchmark. + */ +#include +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +#define FILE_SIZE_MB 5 +#define FILE_SIZE (1000000UL*FILE_SIZE_MB) +#define BUF_SIZE 100 + +uint8_t buf[BUF_SIZE]; + +// file system +SdFat sd; + +// test file +SdFile file; + +// Serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt_P(PSTR(s)) +//------------------------------------------------------------------------------ +void setup() { + uint32_t maxLatency; + uint32_t totalLatency; + Serial.begin(9600); + + // pstr stores strings in flash to save RAM + cout << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} + + cout << pstr("Free RAM: ") << FreeRam() << endl; + + // initialize the SD card at SPI_FULL_SPEED for best performance. + // try SPI_HALF_SPEED if bus errors occur. + if (!sd.init(SPI_FULL_SPEED, chipSelect)) sd.initErrorHalt(); + + cout << pstr("Type is FAT") << int(sd.vol()->fatType()) << endl; + + // open or create file - truncate existing file. + if (!file.open("BENCH.DAT", O_CREAT | O_TRUNC | O_RDWR)) { + error("open failed"); + } + + // fill buf with known data + for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { + buf[i] = 'A' + (i % 26); + } + buf[BUF_SIZE-2] = '\r'; + buf[BUF_SIZE-1] = '\n'; + + cout << pstr("File size ") << FILE_SIZE_MB << pstr("MB\n"); + + cout << pstr("Starting write test. Please wait up to a minute\n"); + + // do write test + uint32_t n = FILE_SIZE/sizeof(buf); + maxLatency = 0; + totalLatency = 0; + uint32_t t = millis(); + for (uint32_t i = 0; i < n; i++) { + uint32_t m = micros(); + if (file.write(buf, sizeof(buf)) != sizeof(buf)) { + error("write failed"); + } + m = micros() - m; + if (maxLatency < m) maxLatency = m; + totalLatency += m; + } + file.sync(); + t = millis() - t; + double s = file.fileSize(); + cout << pstr("Write ") << s/t << pstr(" KB/sec\n"); + cout << pstr("Maximum latency: ") << maxLatency; + cout << pstr(" usec, Avg Latency: ") << totalLatency/n << pstr(" usec\n\n"); + cout << pstr("Starting read test. Please wait up to a minute\n"); + // do read test + file.rewind(); + maxLatency = 0; + totalLatency = 0; + t = millis(); + for (uint32_t i = 0; i < n; i++) { + uint32_t m = micros(); + if (file.read(buf, sizeof(buf)) != sizeof(buf)) { + error("read failed"); + } + m = micros() - m; + if (maxLatency < m) maxLatency = m; + totalLatency += m; + } + t = millis() - t; + cout << pstr("Read ") << s/t << pstr(" KB/sec\n"); + cout << pstr("Maximum latency: ") << maxLatency; + cout << pstr(" usec, Avg Latency: ") << totalLatency/n << pstr(" usec\n\n"); + cout << pstr("Done\n"); +} +//------------------------------------------------------------------------------ +void loop() { } diff --git a/source-1.0L-F11/AVR/SdFat/examples/bufstream/bufstream.pde b/source-1.0L-F11/AVR/SdFat/examples/bufstream/bufstream.pde new file mode 100755 index 0000000..4c0cc72 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/bufstream/bufstream.pde @@ -0,0 +1,31 @@ +/* + * Use of ibufsteam to parse a line and obufstream to format a line + */ +#include + +// create a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void setup() { + char buf[20]; // buffer for formatted line + int i, j, k; // values from parsed line + + Serial.begin(9600); + + // initialize input string + ibufstream bin("123 456 789"); + + // parse the string "123 456 789" + bin >> i >> j >> k; + + // initialize output buffer + obufstream bout(buf, sizeof(buf)); + + // format the output string + bout << k << ',' << j << ',' << i << endl; + + // write the string to serial + cout << buf; +} + +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/cin_cout/cin_cout.pde b/source-1.0L-F11/AVR/SdFat/examples/cin_cout/cin_cout.pde new file mode 100755 index 0000000..f141e7c --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/cin_cout/cin_cout.pde @@ -0,0 +1,33 @@ +/* + * Demo of ArduinoInStream and ArduinoOutStream + */ +#include + +// create serial output stream +ArduinoOutStream cout(Serial); + +// input buffer for line +char cinBuf[40]; + +// create serial input stream +ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); +} +//------------------------------------------------------------------------------ +void loop() { + int32_t n; + + cout << "enter an integer\n"; + + cin.readline(); + + if (cin >> n) { + cout << "The number is: " << n << endl; + } else { + // will fail if no digits or not in range [-2147483648, 2147483647] + cout << "Invalid input: " << cinBuf << endl; + } + cout << endl; +} diff --git a/source-1.0L-F11/AVR/SdFat/examples/eventlog/eventlog.pde b/source-1.0L-F11/AVR/SdFat/examples/eventlog/eventlog.pde new file mode 100755 index 0000000..3ba0c18 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/eventlog/eventlog.pde @@ -0,0 +1,51 @@ +/* + * Append a line to a file - demo of pathnames and streams + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system object +SdFat sd; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +/* + * Append a line to LOGFILE.TXT + */ +void logEvent(const char *msg) { + // create dir if needed + sd.mkdir("LOGS/2011/JAN"); + + // create or open a file for append + ofstream sdlog("LOGS/2011/JAN/LOGFILE.TXT", ios::out | ios::app); + + // append a line to the file + sdlog << msg << endl; + + // check for errors + if (!sdlog) sd.errorHalt("append failed"); + + // file will be closed when sdlog goes out of scope +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // pstr stores strings in flash to save RAM + cout << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // append a line to the logfile + logEvent("Another line for the logfile"); + + cout << "Done - check /LOGS/2011/JAN/LOGFILE.TXT on the SD" << endl; +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/fgets/fgets.pde b/source-1.0L-F11/AVR/SdFat/examples/fgets/fgets.pde new file mode 100755 index 0000000..4ff3f8f --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/fgets/fgets.pde @@ -0,0 +1,66 @@ +// Demo of fgets function to read lines from a file. +#include +SdFat sd; +// print stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash memory +#define error(s) sd.errorHalt_P(PSTR(s)) +//------------------------------------------------------------------------------ +void demoFgets() { + char line[25]; + int n; + // open test file + SdFile rdfile("FGETS.TXT", O_READ); + + // check for open error + if (!rdfile.isOpen()) error("demoFgets"); + + cout << endl << pstr( + "Lines with '>' end with a '\\n' character\n" + "Lines with '#' do not end with a '\\n' character\n" + "\n"); + + // read lines from the file + while ((n = rdfile.fgets(line, sizeof(line))) > 0) { + if (line[n - 1] == '\n') { + cout << '>' << line; + } else { + cout << '#' << line << endl; + } + } +} +//------------------------------------------------------------------------------ +void makeTestFile() { + // create or open test file + SdFile wrfile("FGETS.TXT", O_WRITE | O_CREAT | O_TRUNC); + + // check for open error + if (!wrfile.isOpen()) error("MakeTestFile"); + + // write test file + wrfile.write_P(PSTR( + "Line with CRLF\r\n" + "Line with only LF\n" + "Long line that will require an extra read\n" + "\n" // empty line + "Line at EOF without NL" + )); + // wrfile is closed when it goes out of scope +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + cout << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} + + // initialize the file system + if (!sd.init()) sd.initErrorHalt(); + + makeTestFile(); + + demoFgets(); + + cout << pstr("\nDone\n"); +} +void loop(void) {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/formatting/formatting.pde b/source-1.0L-F11/AVR/SdFat/examples/formatting/formatting.pde new file mode 100755 index 0000000..be63725 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/formatting/formatting.pde @@ -0,0 +1,63 @@ +/* + * Print a table with various formatting options + * Format dates + */ +#include + +// create Serial stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// print a table to demonstrate format manipulators +void example(void) { + const int max = 10; + const int width = 4; + + for (int row = 1; row <= max; row++) { + for (int col = 1; col <= max; col++) { + cout << setw(width) << row * col << (col == max ? '\n' : ' '); + } + } + cout << endl; +} +//------------------------------------------------------------------------------ +// print a date as mm/dd/yyyy with zero fill in mm and dd +// shows how to set and restore the fill character +void showDate(int m, int d, int y) { + // convert two digit year + if (y < 100) y += 2000; + + // set new fill to '0' save old fill character + char old = cout.fill('0'); + + // print date + cout << setw(2) << m << '/' << setw(2) << d << '/' << y << endl; + + // restore old fill character + cout.fill(old); +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + + cout << endl << "default formatting" << endl; + example(); + + cout << showpos << "showpos" << endl; + example(); + + cout << hex << left << showbase << "hex left showbase" << endl; + example(); + + cout << internal << setfill('0') << uppercase; + cout << "uppercase hex internal showbase fill('0')" < + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system object +SdFat sd; + +// create a serial stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void makeTestFile() { + ofstream sdout("GETLINE.TXT"); + // use flash for text to save RAM + sdout << pstr( + "short line\n" + "\n" + "17 character line\n" + "too long for buffer\n" + "line with no nl"); +} +//------------------------------------------------------------------------------ +void testGetline() { + const int line_buffer_size = 18; + char buffer[line_buffer_size]; + ifstream sdin("GETLINE.TXT"); + int line_number = 0; + + while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) { + int count = sdin.gcount(); + if (sdin.fail()) { + cout << "Partial long line"; + sdin.clear(sdin.rdstate() & ~ios_base::failbit); + } else if (sdin.eof()) { + cout << "Partial final line"; // sdin.fail() is false + } else { + count--; // Don’t include newline in count + cout << "Line " << ++line_number; + } + cout << " (" << count << " chars): " << buffer << endl; + } +} +//------------------------------------------------------------------------------ +void setup(void) { + Serial.begin(9600); + + // pstr stores strings in flash to save RAM + cout << pstr("Type any character to start\n"); + while (Serial.read() < 0) {} + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // make the test file + makeTestFile(); + + // run the example + testGetline(); +} +//------------------------------------------------------------------------------ +void loop(void) {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/readCSV/readCSV.pde b/source-1.0L-F11/AVR/SdFat/examples/readCSV/readCSV.pde new file mode 100755 index 0000000..36888dc --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/readCSV/readCSV.pde @@ -0,0 +1,80 @@ +/* + * This example reads a simple CSV, comma-separated values, file. + * Each line of the file has three values, a long and two floats. + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system object +SdFat sd; + +// create Serial stream +ArduinoOutStream cout(Serial); + +char fileName[] = "3V_FILE.CSV"; +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt_P(PSTR(s)) +//------------------------------------------------------------------------------ +// read and print CSV test file +void readFile() { + long lg; + float f1, f2; + char c1, c2; + + // open input file + ifstream sdin(fileName); + + // check for open error + if (!sdin.is_open()) error("open"); + + // read until input fails + while (sdin >> lg >> c1 >> f1 >> c2 >> f2) { + + // error in line if not commas + if (c1 != ',' || c2 != ',') error("comma"); + + // print in six character wide columns + cout << setw(6) << lg << setw(6) << f1 << setw(6) << f2 << endl; + } + // Error in an input line if file is not at EOF. + if (!sdin.eof()) error("readFile"); +} +//------------------------------------------------------------------------------ +// write test file +void writeFile() { + + // create or open and truncate output file + ofstream sdout(fileName); + + // write file from string stored in flash + sdout << pstr( + "1,2.3,4.5\n" + "6,7.8,9.0\n" + "9,8.7,6.5\n" + "-4,-3.2,-1\n") << flush; + + // check for any errors + if (!sdout) error("writeFile"); + + // file is closed by destructor when it goes out of scope. +} +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // create test file + writeFile(); + + // read and print test + readFile(); + + cout << "Done" << endl; +} +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/readlog/readlog.pde b/source-1.0L-F11/AVR/SdFat/examples/readlog/readlog.pde new file mode 100755 index 0000000..e26bfe1 --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/readlog/readlog.pde @@ -0,0 +1,39 @@ +/* + * Read the logfile created by the eventlog.pde example. + * Demo of pathnames and working directories + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system object +SdFat sd; + +// define a serial output stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +void setup() { + char c; + Serial.begin(9600); + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // set current working directory + if (!sd.chdir("LOGS/2011/JAN/")) { + sd.errorHalt("chdir failed. Did you run eventlog.pde?"); + } + // open file in current working directory + ifstream file("LOGFILE.TXT"); + + if (!file.is_open()) sd.errorHalt("open failed"); + + // copy the file to Serial + while ((c = file.get()) >= 0) cout << c; + + cout << "Done" << endl; +} +//------------------------------------------------------------------------------ +void loop() {} diff --git a/source-1.0L-F11/AVR/SdFat/examples/rename/rename.pde b/source-1.0L-F11/AVR/SdFat/examples/rename/rename.pde new file mode 100755 index 0000000..e7757cb --- /dev/null +++ b/source-1.0L-F11/AVR/SdFat/examples/rename/rename.pde @@ -0,0 +1,74 @@ +/* + * This sketch demonstrates use of SdFile::rename() + * and SdFat::rename(). + */ +#include + +// SD chip select pin +const uint8_t chipSelect = SS_PIN; + +// file system +SdFat sd; + +// Serial print stream +ArduinoOutStream cout(Serial); +//------------------------------------------------------------------------------ +// store error strings in flash to save RAM +#define error(s) sd.errorHalt_P(PSTR(s)) +//------------------------------------------------------------------------------ +void setup() { + Serial.begin(9600); + cout << pstr("Insert an empty SD. Type any character to start.") << endl; + while (Serial.read() < 0) {} + + // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with + // breadboards. use SPI_FULL_SPEED for better performance. + if (!sd.init(SPI_HALF_SPEED, chipSelect)) sd.initErrorHalt(); + + // create a file and write one line to the file + SdFile file("NAME1.TXT", O_WRITE | O_CREAT); + if (!file.isOpen()) error("NAME1"); + file.println("A test line for NAME1.TXT"); + + // rename the file NAME2.TXT and add a line. + // sd.vwd() is the volume working directory, root. + if (!file.rename(sd.vwd(), "NAME2.TXT")) error("NAME2"); + file.println("A test line for NAME2.TXT"); + + // list files + cout << pstr("------") << endl; + sd.ls(LS_R); + + // make a new directory - "DIR1" + if (!sd.mkdir("DIR1")) error("DIR1"); + + // move file into DIR1, rename it NAME3.TXT and add a line + if (!file.rename(sd.vwd(), "DIR1/NAME3.TXT")) error("NAME3"); + file.println("A line for DIR1/NAME3.TXT"); + + // list files + cout << pstr("------") << endl; + sd.ls(LS_R); + + // make directory "DIR2" + if (!sd.mkdir("DIR2")) error("DIR2"); + + // close file before rename(oldPath, newPath) + file.close(); + + // move DIR1 into DIR2 and rename it DIR3 + if (!sd.rename("DIR1", "DIR2/DIR3")) error("DIR2/DIR3"); + + // open file for append in new location and add a line + if (!file.open("DIR2/DIR3/NAME3.TXT", O_WRITE | O_APPEND)) { + error("DIR2/DIR3/NAME3.TXT"); + } + file.println("A line for DIR2/DIR3/NAME3.TXT"); + + // list files + cout << pstr("------") << endl; + sd.ls(LS_R); + + cout << pstr("Done") << endl; +} +void loop() {} diff --git a/source-1.0L-F11/AVR/bootldr/bootldr.atsln b/source-1.0L-F11/AVR/bootldr/bootldr.atsln new file mode 100755 index 0000000..54b1a08 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr.atsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# AvrStudio Solution File, Format Version 11.00 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "bootldr", "bootldr\bootldr.cproj", "{4BF88424-65A0-49E2-90B5-584B8FB3E794}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BF88424-65A0-49E2-90B5-584B8FB3E794}.Debug|AVR.ActiveCfg = Debug|AVR + {4BF88424-65A0-49E2-90B5-584B8FB3E794}.Debug|AVR.Build.0 = Debug|AVR + {4BF88424-65A0-49E2-90B5-584B8FB3E794}.Release|AVR.ActiveCfg = Release|AVR + {4BF88424-65A0-49E2-90B5-584B8FB3E794}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/source-1.0L-F11/AVR/bootldr/bootldr.atsuo b/source-1.0L-F11/AVR/bootldr/bootldr.atsuo new file mode 100755 index 0000000..15d378c Binary files /dev/null and b/source-1.0L-F11/AVR/bootldr/bootldr.atsuo differ diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/Release/Makefile b/source-1.0L-F11/AVR/bootldr/bootldr/Release/Makefile new file mode 100755 index 0000000..a1d00c0 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/Release/Makefile @@ -0,0 +1,157 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +SHELL := cmd.exe +RM := rm -rf + +USER_OBJS := + +LIBS := +PROJ := + +O_SRCS := +C_SRCS := +S_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +PREPROCESSING_SRCS := +OBJS := +OBJS_AS_ARGS := +C_DEPS := +C_DEPS_AS_ARGS := +EXECUTABLES := +OUTPUT_FILE_PATH := +OUTPUT_FILE_PATH_AS_ARGS := +AVR_APP_PATH :=$$$AVR_APP_PATH$$$ +QUOTE := " +ADDITIONAL_DEPENDENCIES:= +OUTPUT_FILE_DEP:= + +# Every subdirectory with source files must be described here +SUBDIRS := + + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../lcd.c \ +../main.c \ +../mmc.c \ +../pff.c + + +PREPROCESSING_SRCS += \ +../asmfunc.S + + +ASM_SRCS += + + +OBJS += \ +asmfunc.o \ +lcd.o \ +main.o \ +mmc.o \ +pff.o + + +OBJS_AS_ARGS += \ +asmfunc.o \ +lcd.o \ +main.o \ +mmc.o \ +pff.o + + +C_DEPS += \ +lcd.d \ +main.d \ +mmc.d \ +pff.d + + +C_DEPS_AS_ARGS += \ +lcd.d \ +main.d \ +mmc.d \ +pff.d + + +OUTPUT_FILE_PATH +=bootldr.elf + +OUTPUT_FILE_PATH_AS_ARGS +=bootldr.elf + +ADDITIONAL_DEPENDENCIES:= + +OUTPUT_FILE_DEP:= ./makedep.mk + +# AVR32/GNU C Compiler + + + + + + + + + +./%.o: .././%.c + @echo Building file: $< + @echo Invoking: AVR/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -mcall-prologues -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -DBOOT_ADR=0x1F000 -Os -fdata-sections -ffunction-sections -fpack-struct -fshort-enums -Wall -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<" + @echo Finished building: $< + + + +# AVR32/GNU Preprocessing Assembler + + + +# AVR32/GNU Assembler +./asmfunc.o: .././asmfunc.s + @echo Building file: $< + @echo Invoking: AVR32/GNU C Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -Wa,-gdwarf2 -x assembler-with-cpp -c -DF_CPU=20000000 -DBOOT_ADR=0x1F000 -mmcu=atmega1284p -o"$@" "$<" + @echo Finished building: $< + + +./%.o: .././%.s + @echo Building file: $< + @echo Invoking: AVR32/GNU C Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -Wa,-gdwarf2 -x assembler-with-cpp -c -DF_CPU=20000000 -DBOOT_ADR=0x1F000 -mmcu=atmega1284p -o"$@" "$<" + @echo Finished building: $< + + + + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES) + +$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) + @echo Building target: $@ + @echo Invoking: AVR/GNU C Linker + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="bootldr.map" -Wl,-lm -Wl,--gc-sections -mrelax -Wl,-section-start=.text=0x1f000 -mmcu=atmega1284p + @echo Finished building target: $@ + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "bootldr.elf" "bootldr.hex" + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "bootldr.elf" "bootldr.eep" || exit 0 + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objdump.exe" -h -S "bootldr.elf" > "bootldr.lss" + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-size.exe" -C --mcu=atmega1284p "bootldr.elf" + + + + + +# Other Targets +clean: + -$(RM) $(OBJS_AS_ARGS)$(C_DEPS_AS_ARGS) $(EXECUTABLES) + rm -rf "bootldr.hex" "bootldr.lss" "bootldr.eep" "bootldr.map" + \ No newline at end of file diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/Release/bootldr.hex b/source-1.0L-F11/AVR/bootldr/bootldr/Release/bootldr.hex new file mode 100755 index 0000000..e6004b4 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/Release/bootldr.hex @@ -0,0 +1,259 @@ +:020000021000EC +:10F0000097C00000B2C00000B0C00000AEC0000059 +:10F01000ACC00000AAC00000A8C00000A6C000004C +:10F02000A4C00000A2C00000A0C000009EC000005C +:10F030009CC000009AC0000098C0000096C000006C +:10F0400094C0000092C0000090C000008EC000007C +:10F050008CC000008AC0000088C0000086C000008C +:10F0600084C0000082C0000080C000007EC000009C +:10F070007CC000007AC0000078C0000076C00000AC +:10F0800074C0000072C0000070C000001E051E1F8A +:10F09000150A0E11111F110E1F15151F05050E154E +:10F0A0001D1F041F111F1108100F1F041B1F10101C +:10F0B0001F061F1F0E1F0E110E1F05020010001F3E +:10F0C0000D16121509011F010F101F0718071F0C3D +:10F0D0001F000000031C03000A004552524F525A01 +:10F0E00058464C41534858495358454D505459007F +:10F0F00046454D555142494E584E4F5458464F552E +:10F100004E4400464C415348494E475846454D559C +:10F110005142494E5851515100464C4F5050595848 +:10F12000454D5558424F4F544C4F414445520000B5 +:10F1300011241FBECFEFD0E4DEBFCDBF11E0A0E0B1 +:10F14000B1E0E8EEFFEF01E00BBF02C007900D92C7 +:10F15000AA30B107D9F712E0AAE0B1E001C01D92D0 +:10F16000A733B107E1F7DBD03DC74ACF249A259AF0 +:10F17000279A2E9A089588EC31973197319700009D +:10F180008A95D1F7089502D02C9801C02C9A8FEF60 +:10F1900098E087FD2D9A87FF2D98880F1E998395FB +:10F1A0002F9A2F989A95A9F70895FB018BBF83E0BA +:10F1B00080935700E8958091570080FDFCCF81E156 +:10F1C00080935700E89508950F921F928BBFFB0123 +:10F1D000DA0190E80D901D9081E080935700E8954A +:10F1E00032969A95B9F7FB0185E080935700E89530 +:10F1F0008091570080FDFCCF81E180935700E89516 +:10F200001F900F9008955E9808955E9A0895A1E06A +:10F21000B0E0ECE0F9EFB8C68983B8DF2A988981BD +:10F22000B7DF2A9A2196E2E0CBC6A2E0B0E0EAE19D +:10F23000F9EFAAC66A838983E6DF89818068E7DF00 +:10F240006A81862F8064E3DF2296E2E0B9C6CF931D +:10F25000DF93DBDFC8EFD1E080E0D9DF2197E1F772 +:10F26000DF91CF910895EF92FF920F931F93CF9369 +:10F27000DF938C01CADF1FC023E0829FC0011124ED +:10F280000F5F1F4FEC01C753D0412CECE22E2FEE45 +:10F29000F22EE80EF91ECE01AA2797FDA095BA2FEF +:10F2A000ABBFFC018791880FB2DF2196CE15DF0539 +:10F2B00091F780E0ACDFC801AA2797FDA095BA2F8F +:10F2C000ABBFFC0187918823B9F6CDB7DEB7E6E086 +:10F2D00073C61F93209A229A569A48DF2A98289A32 +:10F2E00018EC49DF1150E9F7289818EC44DF115069 +:10F2F000E9F7289A18EC3FDF1150E9F784DF81E243 +:10F3000086DF8FEB84DF84E182DF80E280DF8CE0C8 +:10F310007EDF80E060E089DF9ADF1F910895A2E040 +:10F32000B0E0E4E9F9EF29C65C9A599A5A9A8FE459 +:10F3300093EC0197F1F700C00000499956C04C9931 +:10F3400054C0239AC6DF89E191EF8DDF80E062E04F +:10F350006CDF8DE091E0A0D280E091E0ACD3882317 +:10F3600009F03AC083E091EF7EDFEE24FF248701AD +:10F370006E010894C11CD11C88E0B82EC801B701E9 +:10F3800014DF87E391E06FEF70E040E051E023D6B7 +:10F3900087E391E060E071E0A601ECD489819A8175 +:10F3A000009729F0C801B70147E351E00DDF85B1AF +:10F3B0008B2585B980E091E0A0E0B0E0E80EF91E71 +:10F3C0000A1F1B1F90E0E91690EFF90691E009076C +:10F3D00090E0190799F603C080EF90EF44DF499B56 +:10F3E000FECF4C9BFCCF4A9BFACF80E090E0FC0123 +:10F3F00025913491AFEF2F3F3A0711F0FC010995A9 +:10F4000068DF80E060E011DF8AED90EF2CDFFFCF56 +:10F41000DF92EF92FF920F931F93182F042FF52E78 +:10F42000E62ED72E87FF08C087E740E050E0BA01FC +:10F43000EFDF8230E0F41F77A6DE812FA9DE8D2D6D +:10F44000A7DE8E2DA5DE8F2DA3DE802FA1DE10344A +:10F4500021F0183421F081E003C085E901C087E87C +:10F4600097DE1AE094DE87FF02C01150D9F71F9192 +:10F470000F91FF90EF90DF900895A5E0B0E0E2E4F7 +:10F48000FAEF7CC573DE04E676DE0150E9F70AE0A8 +:10F490007DDE0150E9F780E440E050E0BA01B8DFDA +:10F4A000813009F067C088E44AEA51E060E070E02A +:10F4B000AFDF8130D1F58E010F5F1F4F45E0C42EC5 +:10F4C000D12CCC0EDD1E780162DEF70181937F0125 +:10F4D000EC15FD05C9F78B81813009F04BC08C819B +:10F4E0008A3A09F047C008C046DE0894E108F108EE +:10F4F000E114F10429F43EC030E1E32E37E2F32EAB +:10F5000089EE40E050E060E070E482DF882361F73C +:10F510003DC03DDEF80181938F01EC15FD05C9F773 +:10F52000898186FF25C09CE026C089EE40E050E03E +:10F53000BA016EDF823020F492E029EEE22E03C0A1 +:10F5400091E081E4E82E00E117E208C09D8313DE1C +:10F55000015010409D810115110561F08E2D40E094 +:10F5600050E0BA019D8354DF9D81882379F717C04D +:10F5700094E001C090E090930A019D8307DE81E052 +:10F580009D81911180E02596E8E014C58AE740E06E +:10F5900050E0BA013DDF882309F4BBCFEBCF80E513 +:10F5A00040E052E060E070E09D8332DF9D8188237F +:10F5B00009F7E1CFA1E0B0E0EFEDFAEFDDC46C01B7 +:10F5C000590180910A0183FD07C0E9E0440F551FEE +:10F5D000661F771FEA95D1F781E51ADF882391F539 +:10F5E00050E4E52E5CE9F52ED2DD8F3F39F4089426 +:10F5F000E108F108E114F104B9F724C08E3F11F5D8 +:10F60000EE24FF24EA18FB0882E092E0E80EF91EDF +:10F61000E01AF10AA114B10429F0B9DD0894A10897 +:10F62000B108F8CFB4DDF60181936F0101501040AD +:10F63000C9F7ADDD0894E108F108E114F104C9F758 +:10F6400080E001C081E08983A1DD89812196EAE023 +:10F65000AFC4CF93DF93C0910B01D0910C016250E6 +:10F660007040804090402E813F81488559852250CE +:10F67000304040405040621773078407950780F47C +:10F680002A8130E040E050E02ED49B01AC018A8911 +:10F690009B89AC89BD89280F391F4A1F5B1F03C096 +:10F6A00020E030E0A901B901CA01DF91CF910895AE +:10F6B000CF93DF93EC01E0910B01F0910C011982E3 +:10F6C00018826C817D818E819F81613071058105F9 +:10F6D000910551F126813781408551856217730765 +:10F6E0008407950708F5611571058105910539F4C1 +:10F6F0002081233021F46685778580899189688708 +:10F7000079878A879B87611571058105910511F0BD +:10F71000A0DF04C066857785808991896C877D87A5 +:10F720008E879F8780E001C081E0DF91CF910895AF +:10F73000A4E0B0E0EDE9FBEF25C4DC01CB01E091F2 +:10F740000B01F0910C0182309105A105B10508F47F +:10F7500052C0268137814085518582179307A407BF +:10F76000B50708F048C02081223021F0233009F08D +:10F7700042C01CC0492F5A2F6B2F77270285138553 +:10F7800024853585400F511F621F731F9C01307007 +:10F79000220F331FCE01019602E010E00BDF882319 +:10F7A00051F529813A8140E050E029C0AC01BD010A +:10F7B00027E076956795579547952A95D1F7028565 +:10F7C000138524853585400F511F621F731F9C01CF +:10F7D0002F773070220F331F220F331FCE01019677 +:10F7E00004E010E0E7DE882331F429813A814B817F +:10F7F0005C815F7004C021E030E040E050E0B9017E +:10F80000CA012496E4E0DAC3A0E0B0E0E9E0FCEF4E +:10F81000B1C3F82EE92E5A016B012EEF31E002E060 +:10F8200010E0C8DE882369F58F2CE4014E019E2C80 +:10F83000E401888199812AEA8535920721F58F2D87 +:10F840009E2DB601A50126E330E0B4DE882331F415 +:10F850008881998121E486349207B9F08F2D9E2DFD +:10F86000B601A50122E530E002E010E0A3DE882326 +:10F8700071F481E02881398191E42634390741F41B +:10F8800004C083E005C082E003C080E001C081E0E5 +:10F89000CDB7DEB7ECE08AC3A8E2B0E0E1E5FCEF6B +:10F8A00065C37C0110920C0110920B01009709F4C2 +:10F8B000F8C0E3DD80FDF7C06E010894C11CD11CC7 +:10F8C000C60140E050E0BA019FDF8130C9F4C601B3 +:10F8D00040E050E0BA012EEB31E000E110E06ADEDA +:10F8E000882309F0E2C08D81882309F4E0C089846F +:10F8F0009A84AB84BC84C601B501A40185DF03C032 +:10F90000882499245401833009F4CFC0882309F056 +:10F91000CEC06E010894C11CD11CC601B501A40162 +:10F920002DE030E004E210E045DE882309F0BDC0A0 +:10F93000D60119966D917C911A9780E090E061153F +:10F9400071058105910521F4688D798D8A8D9B8DD6 +:10F950002C8130E040E050E0C6D26DA37EA38FA39F +:10F9600098A7F6014180528066247724480C591CE0 +:10F970006A1C7B1CD7011A964D925D926D927C9207 +:10F980001D97E9811296EC93D60114964D915C91E6 +:10F990001597D70115965C934E931497D60116963A +:10F9A0006D917C91179780E090E06115710581055C +:10F9B000910521F46C897D898E899F8904E0569593 +:10F9C00047950A95E1F74A01AA24BB24D60111966E +:10F9D0000D911C91129720E030E0601B710B820B9F +:10F9E000930B2DA13EA14FA158A5621B730B840B55 +:10F9F000950B681979098A099B092E2F30E040E0A0 +:10FA000050E090D22E5F3F4F4F4F5F4FD701169679 +:10FA10002D933D934D935C931997273FBFE03B0790 +:10FA2000B0E04B07B0E05B0708F441C0273FEFEFC1 +:10FA30003E07E0E04E07E0E05E0710F482E001C020 +:10FA400083E0D7018C93833029F488A199A1AAA1DE +:10FA5000BBA108C08DA19EA1AFA1B8A5840D951D25 +:10FA6000A61DB71DF70186879787A08BB18B480C21 +:10FA7000591C6A1C7B1C2DA13EA14FA158A5420E0A +:10FA8000531E641E751ED70152964D925D926D9263 +:10FA90007C92559711961C921197F0920C01E0926E +:10FAA0000B0180E005C082E003C081E001C087E077 +:10FAB000A896E0E177C2ACE3B0E0E0E6FDEF54C227 +:10FAC000C0900B01D0900C01C114D10409F446C1BF +:10FAD000F60111829E012F5F3F4F388B2F877C01EB +:10FAE000FC01208101962032D1F32F3209F47C01F0 +:10FAF000198A1A8A1B8A1C8AF7018081813240F494 +:10FB0000CE010D96D5DD1D8E882309F4F7C029C1DD +:10FB100090E2892E8DE0482E512C4C0E5D1EBDE1E9 +:10FB20006B2E712C6C0E7D1EA8E22A2E312C2C0E11 +:10FB30003D1EEF85F889DF01CF010B9601C08D9244 +:10FB4000A817B907E1F790E0992428E0D701A90D9B +:10FB5000B11D8C9193948132C0F08F32B1F08E320E +:10FB600011F0921738F0283081F48E3271F498E059 +:10FB70002BE0ECCF382F31563A3108F48052DF01B8 +:10FB8000A90FB11D8C939F5FE1CF91E0813208F006 +:10FB900090E09387C2018CDD882309F086C0498DEF +:10FBA0005A8D6B8D7C8D2D853E852F703070F5E0E4 +:10FBB000220F331FFA95E1F7C30100E210E0FADCEF +:10FBC000882309F0D1C08D8D882309F4CFC088A582 +:10FBD00083FD0BC0F301AF85B889E215F30509F485 +:10FBE0006EC091918D919817C1F3A0900B01B090C8 +:10FBF0000C010D851E850F5F1F4F09F4B7C0898D5D +:10FC00009A8DAB8DBC8D0097A105B10509F4AEC0EE +:10FC100098012F7030702115310509F043C001960D +:10FC2000A11DB11D898F9A8FAB8FBC8F6D897E8985 +:10FC30008F89988D611571058105910541F4F50154 +:10FC4000848195810817190708F090C02BC0F50131 +:10FC5000228130E021503040A801E4E056954795DC +:10FC6000EA95E1F72423352321153105D9F460DD28 +:10FC7000623071058105910508F476C0F501268191 +:10FC8000378140855185621773078407950708F00F +:10FC90006DC06D8B7E8B8F8B988FDBDC698F7A8F3D +:10FCA0008B8F9C8F1E870D877ACF833009F059C0C8 +:10FCB000EF85F8899385992309F45AC052C0EF85DE +:10FCC000F88983858823D1F488A584FF51C0E90C85 +:10FCD000F11CF30184899589A0E0B0E0DC0199274B +:10FCE0008827228D338D40E050E0822B932BA42B6C +:10FCF000B52B898B9A8BAB8BBC8B1BCF8D8D8823BF +:10FD000079F188A584FD2CC0BE01635E7F4FFB01A5 +:10FD100084899589A0E0B0E0DC0199278827228DAD +:10FD2000338D40E050E0822B932BA42BB52BF601B2 +:10FD3000868F978FA0A3B1A3FB01848D958DA68D8F +:10FD4000B78DF601828F938FA48FB58F168A178A8D +:10FD5000108E118E81E0818380E003C086E001C0B7 +:10FD600083E0EC96E2E11CC181E0FBCF83E0A0CF11 +:10FD700084E0F7CFA0E0B0E0EFEBFEEFF7C03C018E +:10FD80007B014A01C0910B01D0910C01FA01118253 +:10FD90001082209709F4A0C0898180FF9FC08A8DBE +:10FDA0009B8DAC8DBD8D2E893F89488D598D821BD1 +:10FDB000930BA40BB50B9B0140E050E08217930717 +:10FDC000A407B50708F47C015301412C72E0572EBB +:10FDD0007AC08E899F89A88DB98D9C01AD01317043 +:10FDE000407050702115310541055105C1F59C0148 +:10FDF000AD0169E056954795379527956A95D1F7F6 +:10FE0000CA80CA94C222C1F40097A105B10529F4A1 +:10FE10006E8D7F8D88A199A105C06AA17BA18CA15F +:10FE20009DA186DC623071058105910508F451C001 +:10FE30006AA37BA38CA39DA36AA17BA18CA19DA196 +:10FE400008DC611571058105910509F442C06C0D4E +:10FE5000711D811D911D6EA37FA388A799A72E896F +:10FE60003F893170C201821B930B67018E159F057C +:10FE700008F46C016114710419F480E090E001C091 +:10FE8000C5014EA15FA168A579A5860193DB8823F2 +:10FE900001F5960140E050E08E899F89A88DB98DCB +:10FEA000820F931FA41FB51F8E8B9F8BA88FB98FB6 +:10FEB000AC0CBD1CEC18FD08F401808191818C0D07 +:10FEC0009D1D91838083E114F10409F082CF80E0CD +:10FED00006C0198281E003C086E001C085E0CDB78D +:10FEE000DEB7E0E15FC0629FD001739FF001829FA7 +:10FEF000E00DF11D649FE00DF11D929FF00D839FB9 +:10FF0000F00D749FF00D659FF00D9927729FB00D55 +:10FF1000E11DF91F639FB00DE11DF91FBD01CF0168 +:10FF200011240895A1E21A2EAA1BBB1BFD010DC0CE +:10FF3000AA1FBB1FEE1FFF1FA217B307E407F50799 +:10FF400020F0A21BB30BE40BF50B661F771F881F75 +:10FF5000991F1A9469F760957095809590959B010B +:10FF6000AC01BD01CF0108952F923F924F925F9255 +:10FF70006F927F928F929F92AF92BF92CF92DF92B9 +:10FF8000EF92FF920F931F93CF93DF93CDB7DEB71E +:10FF9000CA1BDB0B0FB6F894DEBF0FBECDBF0994B2 +:10FFA0002A88398848885F846E847D848C849B8409 +:10FFB000AA84B984C884DF80EE80FD800C811B8117 +:10FFC000AA81B981CE0FD11D0FB6F894DEBF0FBE46 +:10FFD000CDBFED010895DC0101C06D93415050404B +:08FFE000E0F70895F894FFCF4B +:0AFFE80066656D752E62696E0000FB +:040000031000F000F9 +:00000001FF diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/Release/makedep.mk b/source-1.0L-F11/AVR/bootldr/bootldr/Release/makedep.mk new file mode 100755 index 0000000..d9e3cb3 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/Release/makedep.mk @@ -0,0 +1,14 @@ +################################################################################ +# Automatically-generated file. Do not edit or delete the file +################################################################################ + +asmfunc.S + +lcd.c + +main.c + +mmc.c + +pff.c + diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/asmfunc.S b/source-1.0L-F11/AVR/bootldr/bootldr/asmfunc.S new file mode 100755 index 0000000..ebe2533 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/asmfunc.S @@ -0,0 +1,212 @@ +;---------------------------------------------------------------------------; +; MMC hardware controls and Flash controls (C)ChaN, 2010 +;---------------------------------------------------------------------------; +; Hardware dependent macros to be modified + +#define DDR_CS _SFR_IO_ADDR(DDRB), 4 // MMC CS pin (DDR, PORT) +#define PORT_CS _SFR_IO_ADDR(PORTB), 4 + +#define DDR_CK _SFR_IO_ADDR(DDRB), 7 // MMC SCLK pin (DDR, PORT) +#define PORT_CK _SFR_IO_ADDR(PORTB), 7 + +#define DDR_DI _SFR_IO_ADDR(DDRB), 5 // MMC DI pin (DDR, PORT) +#define PORT_DI _SFR_IO_ADDR(PORTB), 5 + +#define PIN_DO _SFR_IO_ADDR(PINB), 6 // MMC DO pin (PIN, PORT) +#define PORT_DO _SFR_IO_ADDR(PORTB), 6 + + +;---------------------------------------------------------------------------; +.nolist +#include +.list +.text + + +;---------------------------------------------------------------------------; +; Initialize MMC port +; +; void init_spi (void); + +.global init_spi +.func init_spi +init_spi: + sbi DDR_CS ; CS: output + sbi DDR_DI ; DI: output + sbi DDR_CK ; SCLK: output + sbi PORT_DO ; DO: pull-up + ret +.endfunc + + + +;---------------------------------------------------------------------------; +; Delay 100 microseconds +; +; void dly_us (UINT n); + +.global dly_100us +.func dly_100us +dly_100us: + ldi r24, lo8(F_CPU / 100000) /* Loop counter */ +1: sbiw r30, 1 /* 10 clocks per loop */ + sbiw r30, 1 + sbiw r30, 1 + nop + dec r24 + brne 1b + ret +.endfunc + + + +;---------------------------------------------------------------------------; +; Select MMC +; +; void select (void); + +.global select +.func select +select: + rcall deselect + cbi PORT_CS + rjmp rcv_spi +.endfunc + + + +;---------------------------------------------------------------------------; +; Deselect MMC +; +; void deselect (void); + +.global deselect +.func deselect +deselect: + sbi PORT_CS + ; Goto next function +.endfunc + + + +;---------------------------------------------------------------------------; +; Receive a byte +; +; BYTE rcv_spi (void); + +.global rcv_spi +.func rcv_spi +rcv_spi: + ldi r24, 0xFF ; Send 0xFF to receive data + ; Goto next function +.endfunc + + + +;---------------------------------------------------------------------------; +; Transmit a byte +; +; void xmit_spi (BYTE); + +.global xmit_spi +.func xmit_spi +xmit_spi: + ldi r25, 8 +1: sbrc r24, 7 ; DI = Bit to sent + sbi PORT_DI ; + sbrs r24, 7 ; + cbi PORT_DI ; / + lsl r24 ; Get DO from MMC + sbic PIN_DO ; + inc r24 ; / + sbi PORT_CK ; A positive pulse to SCLK + cbi PORT_CK ; / + dec r25 ; Repeat 8 times + brne 1b ; / + ret +.endfunc + + + +;--------------------------------------------------------------------------- +; Erase a flash page +; +; void flash_erase (DWORD flash_addr); + +.global flash_erase +.func flash_erase +flash_erase: + + movw ZL, r22 +#if FLASHEND >= 0x10000 + out _SFR_IO_ADDR(RAMPZ), r24 +#endif + + ; Initiate erase operation + ldi r24, 0b00000011 + sts _SFR_MEM_ADDR(SPMCSR), r24 + spm + + ; Wait for end of erase operation +1: lds r24, _SFR_MEM_ADDR(SPMCSR) + sbrc r24, 0 + rjmp 1b + + ; Re-enable read access to the flash + ldi r24, 0b00010001 + sts _SFR_MEM_ADDR(SPMCSR), r24 + spm + +9: ret +.endfunc + + + +;--------------------------------------------------------------------------- +; Write a flash page +; +; void flash_write (DWORD flash_addr, const BYTE* data); + +.global flash_write +.func flash_write +flash_write: + push r0 + push r1 + +#if FLASHEND >= 0x10000 + out _SFR_IO_ADDR(RAMPZ), r24 +#endif + + ; Fill page buffer + movw ZL, r22 + movw XL, r20 + ldi r25, lo8(SPM_PAGESIZE/2) +1: ld r0, X+ + ld r1, X+ + ldi r24, 0b00000001 + sts _SFR_MEM_ADDR(SPMCSR), r24 + spm + adiw ZL, 2 + dec r25 + brne 1b + + ; Initiate write operation + movw ZL, r22 + ldi r24, 0b00000101 + sts _SFR_MEM_ADDR(SPMCSR), r24 + spm + + ; Wait for end of write operation +2: lds r24, _SFR_MEM_ADDR(SPMCSR) + sbrc r24, 0 + rjmp 2b + + ; Re-enable read access to the flash + ldi r24, 0b00010001 + sts _SFR_MEM_ADDR(SPMCSR), r24 + spm + +9: pop r1 + pop r0 + ret +.endfunc diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/bootldr.c b/source-1.0L-F11/AVR/bootldr/bootldr/bootldr.c new file mode 100755 index 0000000..4dd3b47 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/bootldr.c @@ -0,0 +1,16 @@ +/* + * bootldr.c + * + * Created: 10/6/2013 12:43:37 PM + * Author: chamberlin + */ + +#include + +int main(void) +{ + while(1) + { + //TODO:: Please write your application code + } +} \ No newline at end of file diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/bootldr.cproj b/source-1.0L-F11/AVR/bootldr/bootldr/bootldr.cproj new file mode 100755 index 0000000..6b7b817 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/bootldr.cproj @@ -0,0 +1,109 @@ + + + + 2.0 + 5.1 + com.Atmel.AVRGCC8 + {4bf88424-65a0-49e2-90b5-584b8fb3e794} + ATmega1284P + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + bootldr + bootldr + bootldr + Native + 2.11.1 + + + + + True + True + True + + + F_CPU=20000000 + BOOT_ADR=0x1F000 + + + Optimize for size (-Os) + -fdata-sections + True + True + True + True + + + m + + + True + True + + + .text=0xF800 + + + + + F_CPU=20000000 + BOOT_ADR=0x1F000 + + + + + + + + + True + True + True + True + Optimize (-O1) + Default (-g2) + True + Default (-g2) + + + m + + + + + + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + \ No newline at end of file diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/diskio.h b/source-1.0L-F11/AVR/bootldr/bootldr/diskio.h new file mode 100755 index 0000000..e2a1553 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/diskio.h @@ -0,0 +1,41 @@ +/*----------------------------------------------------------------------- +/ PFF - Low level disk interface modlue include file (C)ChaN, 2009 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Function succeeded */ + RES_ERROR, /* 1: Disk error */ + RES_NOTRDY, /* 2: Not ready */ + RES_PARERR /* 3: Invalid parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +DSTATUS disk_initialize (void); +DRESULT disk_readp (BYTE*, DWORD, WORD, WORD); +DRESULT disk_writep (const BYTE*, DWORD); + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ + +/* Card type flags (CardType) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ + +#define _DISKIO +#endif diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/integer.h b/source-1.0L-F11/AVR/bootldr/bootldr/integer.h new file mode 100755 index 0000000..137b988 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/lcd.c b/source-1.0L-F11/AVR/bootldr/bootldr/lcd.c new file mode 100755 index 0000000..b73a8ea --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/lcd.c @@ -0,0 +1,149 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#include +#include +#include + +void init_spi (void); /* Initialize SPI port (asmfunc.S) */ +void deselect (void); /* Select MMC (asmfunc.S) */ +void select (void); /* Deselect MMC (asmfunc.S) */ +void xmit_spi (uint8_t d); /* Send a byte to the MMC (asmfunc.S) */ +void dly_100us (void); /* Delay 100 microseconds (asmfunc.S) */ + +extern const uint8_t tiny_font[][3] PROGMEM; +const uint8_t tiny_font[][3] = { + {0x1e,0x05,0x1e}, // 41 A + {0x1f,0x15,0x0a}, // 42 B + {0x0e,0x11,0x11}, // 43 C + {0x1f,0x11,0x0e}, // 44 D + {0x1f,0x15,0x15}, // 45 E + {0x1f,0x05,0x05}, // 46 F + {0x0e,0x15,0x1d}, // 47 G + {0x1f,0x04,0x1f}, // 48 H + {0x11,0x1f,0x11}, // 49 I + {0x08,0x10,0x0f}, // 4a J + {0x1f,0x04,0x1b}, // 4b K + {0x1f,0x10,0x10}, // 4c L + {0x1f,0x06,0x1f}, // 4d M + {0x1f,0x0e,0x1f}, // 4e N + {0x0e,0x11,0x0e}, // 4f O + {0x1f,0x05,0x02}, // 50 P + {0x00,0x10,0x00}, // 51 . (not Q) + {0x1f,0x0d,0x16}, // 52 R + {0x12,0x15,0x09}, // 53 S + {0x01,0x1f,0x01}, // 54 T + {0x0f,0x10,0x1f}, // 55 U + {0x07,0x18,0x07}, // 56 V + {0x1f,0x0c,0x1f}, // 57 W + {0x00,0x00,0x00}, // 58 space (not X) + {0x03,0x1c,0x03}, // 59 Y + {0x00,0x0a,0x00} // 5a : (not Z) +}; + +#define LCD_DDR DDRB +#define LCD_PORT PORTB +#define LCD_RESET_PIN_NUMBER 0 +#define LCD_CS_PIN_NUMBER 2 +#define LCD_DC_DDR DDRD +#define LCD_DC_PORT PORTD +#define LCD_DC_PIN_NUMBER 6 + +void LcdCommand() +{ + LCD_DC_PORT &= ~(1< +#include +#include +#include +#include "pff.h" +#include "lcd.h" + +void flash_erase (DWORD); /* Erase a flash page (asmfunc.S) */ +void flash_write (DWORD, const BYTE*); /* Program a flash page (asmfunc.S) */ + +FATFS Fatfs; /* Petit-FatFs work area */ +BYTE Buff[SPM_PAGESIZE]; /* Page data buffer */ + +#define BUTTON_PORT PORTD +#define BUTTON_PIN PIND +#define SELECT_BUTTON_PIN 4 +#define PREV_BUTTON_PIN 1 +#define NEXT_BUTTON_PIN 2 + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_NUMBER 3 + +int main (void) +{ + DWORD fa; /* Flash address */ + WORD br; /* Bytes read */ + + // enable the pull-up resistor for the user buttons + BUTTON_PORT |= (1< is the command sequense of CMD55-CMD */ + cmd &= 0x7F; + res = send_cmd(CMD55, 0); + if (res > 1) return res; + } + + /* Select the card */ + select(); + + /* Send a command packet */ + xmit_spi(cmd); /* Start + Command index */ + xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ + xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ + xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ + xmit_spi((BYTE)arg); /* Argument[7..0] */ + n = 0x01; /* Dummy CRC + Stop */ + if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ + if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ + xmit_spi(n); + + /* Receive a command response */ + n = 10; /* Wait for a valid response in timeout of 10 attempts */ + do { + res = rcv_spi(); + } while ((res & 0x80) && --n); + + return res; /* Return with the response value */ +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +---------------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------*/ +/* Initialize Disk Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize (void) +{ + BYTE n, cmd, ty, ocr[4]; + UINT tmr; + + + init_spi(); /* Initialize ports to control MMC */ + for (n = 100; n; n--) dly_100us(); /* 10ms delay */ + for (n = 10; n; n--) deselect(); /* 80 Dummy clocks with CS=H */ + + ty = 0; + if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ + if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */ + for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); /* Get trailing return value of R7 resp */ + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ + for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) dly_100us(); /* Wait for leaving idle state (ACMD41 with HCS bit) */ + if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ + for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); + ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ + } + } + } else { /* SDv1 or MMCv3 */ + if (send_cmd(ACMD41, 0) <= 1) { + ty = CT_SD1; cmd = ACMD41; /* SDv1 */ + } else { + ty = CT_MMC; cmd = CMD1; /* MMCv3 */ + } + for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) dly_100us(); /* Wait for leaving idle state */ + if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ + ty = 0; + } + } + CardType = ty; + deselect(); + + return ty ? 0 : STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read partial sector */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_readp ( + BYTE *buff, /* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */ + DWORD lba, /* Sector number (LBA) */ + WORD ofs, /* Byte offset to read from (0..511) */ + WORD cnt /* Number of bytes to read (ofs + cnt mus be <= 512) */ +) +{ + DRESULT res; + BYTE rc; + WORD bc; + + + if (!(CardType & CT_BLOCK)) lba *= 512; /* Convert to byte address if needed */ + + res = RES_ERROR; + if (send_cmd(CMD17, lba) == 0) { /* READ_SINGLE_BLOCK */ + + bc = 40000; + do { /* Wait for data packet */ + rc = rcv_spi(); + } while (rc == 0xFF && --bc); + + if (rc == 0xFE) { /* A data packet arrived */ + bc = 514 - ofs - cnt; + + /* Skip leading bytes */ + if (ofs) { + do rcv_spi(); while (--ofs); + } + + /* Receive a part of the sector */ + do { + *buff++ = rcv_spi(); + } while (--cnt); + + /* Skip trailing bytes and CRC */ + do rcv_spi(); while (--bc); + + res = RES_OK; + } + } + + deselect(); + + return res; +} + + diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/pff.c b/source-1.0L-F11/AVR/bootldr/bootldr/pff.c new file mode 100755 index 0000000..802e8a3 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/pff.c @@ -0,0 +1,1114 @@ +/*----------------------------------------------------------------------------/ +/ Petit FatFs - FAT file system module R0.02a (C)ChaN, 2010 +/-----------------------------------------------------------------------------/ +/ Petit FatFs module is an open source software to implement FAT file system to +/ small embedded systems. This is a free software and is opened for education, +/ research and commercial developments under license policy of following trems. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The Petit FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.) +/ +/ Dec 14,'09 R0.02 Added multiple code page support. +/ Added write funciton. +/ Changed stream read mode interface. +/ Dec 07,'10 R0.02a Added some configuration options. +/ Fixed fails to open objects with DBCS character. +/----------------------------------------------------------------------------*/ + +#include "pff.h" /* Petit FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + + +#if _FS_FAT32 +#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO)) +#else +#define LD_CLUST(dir) LD_WORD(dir+DIR_FstClusLO) +#endif + + +/*--------------------------------------------------------*/ +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Character code support macros */ + +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) + +#if _DF1S /* DBCS configuration */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* SBCS configuration */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* FatFs refers the members in the FAT structures with byte offset instead +/ of structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 + + + +/*-------------------------------------------------------------------------- + + Private Functions + +---------------------------------------------------------------------------*/ + + +static +FATFS *FatFs; /* Pointer to the file system object (logical drive) */ + + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + char *d = (char*)dst; + while (cnt--) *d++ = (char)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const char *d = (const char *)dst, *s = (const char *)src; + int r = 0; + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + +static +CLUST get_fat ( /* 1:IO error, Else:Cluster status */ + CLUST clst /* Cluster# to get the link information */ +) +{ + WORD wc, bc, ofs; + BYTE buf[4]; + FATFS *fs = FatFs; + + + if (clst < 2 || clst >= fs->n_fatent) /* Range check */ + return 1; + + switch (fs->fs_type) { +#if _FS_FAT12 + case FS_FAT12 : + bc = (WORD)clst; bc += bc / 2; + ofs = bc % 512; bc /= 512; + if (ofs != 511) { + if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break; + } else { + if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break; + if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break; + } + wc = LD_WORD(buf); + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); +#endif + case FS_FAT16 : + if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break; + return LD_WORD(buf); +#if _FS_FAT32 + case FS_FAT32 : + if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break; + return LD_DWORD(buf) & 0x0FFFFFFF; +#endif + } + + return 1; /* An error occured at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + +static +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + CLUST clst /* Cluster# to be converted */ +) +{ + FATFS *fs = FatFs; + + + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return (DWORD)clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Rewind directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_rewind ( + DIR *dj /* Pointer to directory object */ +) +{ + CLUST clst; + FATFS *fs = FatFs; + + + dj->index = 0; + clst = dj->sclust; + if (clst == 1 || clst >= fs->n_fatent) /* Check start cluster range */ + return FR_DISK_ERR; + if (_FS_FAT32 && !clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = (CLUST)fs->dirbase; + dj->clust = clst; /* Current cluster */ + dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */ + DIR *dj /* Pointer to directory object */ +) +{ + CLUST clst; + WORD i; + FATFS *fs = FatFs; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % 16)) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_DISK_ERR; + if (clst >= fs->n_fatent) /* When it reached end of dynamic table */ + return FR_NO_FILE; /* Report EOT */ + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(clst); + } + } + } + + dj->index = i; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj, /* Pointer to the directory object linked to the file name */ + BYTE *dir /* 32-byte working buffer */ +) +{ + FRESULT res; + BYTE c; + + + res = dir_rewind(dj); /* Rewind directory object */ + if (res != FR_OK) return res; + + do { + res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */ + ? FR_DISK_ERR : FR_OK; + if (res != FR_OK) break; + c = dir[DIR_Name]; /* First character */ + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; + res = dir_next(dj); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _USE_DIR +static +FRESULT dir_read ( + DIR *dj, /* Pointer to the directory object to store read object name */ + BYTE *dir /* 32-byte working buffer */ +) +{ + FRESULT res; + BYTE a, c; + + + res = FR_NO_FILE; + while (dj->sect) { + res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */ + ? FR_DISK_ERR : FR_OK; + if (res != FR_OK) break; + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ + a = dir[DIR_Attr] & AM_MASK; + if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */ + break; + res = dir_next(dj); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +#ifdef _EXCVT + static const BYTE cvt[] = _EXCVT; +#endif + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const char **path /* Pointer to pointer to the segment in the path string */ +) +{ + BYTE c, d, ni, si, i, *sfn; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = 0; ni = 8; + p = *path; + for (;;) { + c = p[si++]; + if (c <= ' ' || c == '/') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') break; + i = 8; ni = 11; + continue; + } +#ifdef _EXCVT + if (c >= 0x80) /* To upper extended char (SBCS) */ + c = cvt[c - 0x80]; +#endif + if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */ + d = p[si++]; /* Get 2nd byte */ + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (IsLower(c)) c -= 0x20; /* toupper */ + sfn[i++] = c; + } + } + *path = &p[si]; /* Rerurn pointer to the next segment */ + + sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_DIR +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + BYTE *dir, /* 32-byte working buffer */ + FILINFO *fno /* Pointer to store the file information */ +) +{ + BYTE i, c; + char *p; + + + p = fno->fname; + if (dj->sect) { + for (i = 0; i < 8; i++) { /* Copy file name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = 0xE5; + *p++ = c; + } + if (dir[8] != ' ') { /* Copy file name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; +} +#endif /* _USE_DIR */ + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + BYTE *dir, /* 32-byte working buffer */ + const char *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + + + while (*path == ' ') path++; /* Skip leading spaces */ + if (*path == '/') path++; /* Strip heading separator */ + dj->sclust = 0; /* Set start directory (always root dir) */ + + if ((BYTE)*path <= ' ') { /* Null path means the root directory */ + res = dir_rewind(dj); + dir[0] = 0; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj, dir); /* Find it */ + if (res != FR_OK) { /* Could not find the object */ + if (res == FR_NO_FILE && !*(dj->fn+11)) + res = FR_NO_PATH; + break; + } + if (*(dj->fn+11)) break; /* Last segment match. Function completed. */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = LD_CLUST(dir); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check a sector if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */ + BYTE *buf, /* Working buffer */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */ + return 3; + if (LD_WORD(buf) != 0xAA55) /* Check record signature */ + return 2; + + if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */ + return 0; + if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */ + return 0; + return 1; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Locical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT pf_mount ( + FATFS *fs /* Pointer to new file system object (NULL: Unmount) */ +) +{ + BYTE fmt, buf[36]; + DWORD bsect, fsize, tsect, mclst; + + + FatFs = 0; + if (!fs) return FR_OK; /* Unregister fs object */ + + if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */ + return FR_NOT_READY; + + /* Search FAT partition on the drive */ + bsect = 0; + fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */ + if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */ + /* Check a partition listed in top of the partition table */ + if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */ + fmt = 3; + } else { + if (buf[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */ + fmt = check_fs(buf, bsect); /* Check the partition */ + } + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */ + + /* Initialize the file system object */ + if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR; + + fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */ + if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13); + + fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */ + fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */ + fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */ + fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */ + tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */ + if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13); + mclst = (tsect /* Last cluster# + 1 */ + - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16 + ) / fs->csize + 2; + fs->n_fatent = (CLUST)mclst; + + fmt = FS_FAT16; /* Determine the FAT sub type */ + if (mclst < 0xFF7) /* Number of clusters < 0xFF5 */ +#if _FS_FAT12 + fmt = FS_FAT12; +#else + return FR_NO_FILESYSTEM; +#endif + if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */ +#if _FS_FAT32 + fmt = FS_FAT32; +#else + return FR_NO_FILESYSTEM; +#endif + + fs->fs_type = fmt; /* FAT sub-type */ + if (_FS_FAT32 && fmt == FS_FAT32) + fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */ + else + fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */ + fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */ + + fs->flag = 0; + FatFs = fs; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT pf_open ( + const char *path /* Pointer to the file name */ +) +{ + FRESULT res; + DIR dj; + BYTE sp[12], dir[32]; + FATFS *fs = FatFs; + + + if (!fs) /* Check file system */ + return FR_NOT_ENABLED; + + fs->flag = 0; + dj.fn = sp; + res = follow_path(&dj, dir, path); /* Follow the file path */ + if (res != FR_OK) return res; /* Follow failed */ + if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */ + return FR_NO_FILE; + + fs->org_clust = LD_CLUST(dir); /* File start cluster */ + fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fs->fptr = 0; /* File pointer */ + fs->flag = FA_OPENED; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ +#if _USE_READ + +FRESULT pf_read ( + void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/ + WORD btr, /* Number of bytes to read */ + WORD* br /* Pointer to number of bytes read */ +) +{ + DRESULT dr; + CLUST clst; + DWORD sect, remain; + WORD rcnt; + BYTE cs, *rbuff = buff; + FATFS *fs = FatFs; + + + *br = 0; + if (!fs) return FR_NOT_ENABLED; /* Check file system */ + if (!(fs->flag & FA_OPENED)) /* Check if opened */ + return FR_NOT_OPENED; + + remain = fs->fsize - fs->fptr; + if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */ + + while (btr) { /* Repeat until all data transferred */ + if ((fs->fptr % 512) == 0) { /* On the sector boundary? */ + cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */ + if (!cs) { /* On the cluster boundary? */ + clst = (fs->fptr == 0) ? /* On the top of the file? */ + fs->org_clust : get_fat(fs->curr_clust); + if (clst <= 1) goto fr_abort; + fs->curr_clust = clst; /* Update current cluster */ + } + sect = clust2sect(fs->curr_clust); /* Get current sector */ + if (!sect) goto fr_abort; + fs->dsect = sect + cs; + } + rcnt = (WORD)(512 - (fs->fptr % 512)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; + dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt); + if (dr) goto fr_abort; + fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */ + btr -= rcnt; *br += rcnt; + } + + return FR_OK; + +fr_abort: + fs->flag = 0; + return FR_DISK_ERR; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ +#if _USE_WRITE + +FRESULT pf_write ( + const void* buff, /* Pointer to the data to be written */ + WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */ + WORD* bw /* Pointer to number of bytes written */ +) +{ + CLUST clst; + DWORD sect, remain; + const BYTE *p = buff; + BYTE cs; + WORD wcnt; + FATFS *fs = FatFs; + + + *bw = 0; + if (!fs) return FR_NOT_ENABLED; /* Check file system */ + if (!(fs->flag & FA_OPENED)) /* Check if opened */ + return FR_NOT_OPENED; + + if (!btw) { /* Finalize request */ + if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort; + fs->flag &= ~FA__WIP; + return FR_OK; + } else { /* Write data request */ + if (!(fs->flag & FA__WIP)) /* Round-down fptr to the sector boundary */ + fs->fptr &= 0xFFFFFE00; + } + remain = fs->fsize - fs->fptr; + if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */ + + while (btw) { /* Repeat until all data transferred */ + if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */ + cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */ + if (!cs) { /* On the cluster boundary? */ + clst = (fs->fptr == 0) ? /* On the top of the file? */ + fs->org_clust : get_fat(fs->curr_clust); + if (clst <= 1) goto fw_abort; + fs->curr_clust = clst; /* Update current cluster */ + } + sect = clust2sect(fs->curr_clust); /* Get current sector */ + if (!sect) goto fw_abort; + fs->dsect = sect + cs; + if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */ + fs->flag |= FA__WIP; + } + wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */ + if (wcnt > btw) wcnt = btw; + if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */ + fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */ + btw -= wcnt; *bw += wcnt; + if (((WORD)fs->fptr % 512) == 0) { + if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */ + fs->flag &= ~FA__WIP; + } + } + + return FR_OK; + +fw_abort: + fs->flag = 0; + return FR_DISK_ERR; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ +#if _USE_LSEEK + +FRESULT pf_lseek ( + DWORD ofs /* File pointer from top of file */ +) +{ + CLUST clst; + DWORD bcs, sect, ifptr; + FATFS *fs = FatFs; + + + if (!fs) return FR_NOT_ENABLED; /* Check file system */ + if (!(fs->flag & FA_OPENED)) /* Check if opened */ + return FR_NOT_OPENED; + + if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */ + ifptr = fs->fptr; + fs->fptr = 0; + if (ofs > 0) { + bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fs->fptr; + clst = fs->curr_clust; + } else { /* When seek to back cluster, */ + clst = fs->org_clust; /* start from the first cluster */ + fs->curr_clust = clst; + } + while (ofs > bcs) { /* Cluster following loop */ + clst = get_fat(clst); /* Follow cluster chain */ + if (clst <= 1 || clst >= fs->n_fatent) goto fe_abort; + fs->curr_clust = clst; + fs->fptr += bcs; + ofs -= bcs; + } + fs->fptr += ofs; + sect = clust2sect(clst); /* Current sector */ + if (!sect) goto fe_abort; + fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1)); + } + + return FR_OK; + +fe_abort: + fs->flag = 0; + return FR_DISK_ERR; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ +#if _USE_DIR + +FRESULT pf_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const char *path /* Pointer to the directory path */ +) +{ + FRESULT res; + BYTE sp[12], dir[32]; + FATFS *fs = FatFs; + + + if (!fs) { /* Check file system */ + res = FR_NOT_ENABLED; + } else { + dj->fn = sp; + res = follow_path(dj, dir, path); /* Follow the path to the directory */ + if (res == FR_OK) { /* Follow completed */ + if (dir[0]) { /* It is not the root dir */ + if (dir[DIR_Attr] & AM_DIR) /* The object is a directory */ + dj->sclust = LD_CLUST(dir); + else /* The object is not a directory */ + res = FR_NO_PATH; + } + if (res == FR_OK) + res = dir_rewind(dj); /* Rewind dir */ + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT pf_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + BYTE sp[12], dir[32]; + FATFS *fs = FatFs; + + + if (!fs) { /* Check file system */ + res = FR_NOT_ENABLED; + } else { + dj->fn = sp; + if (!fno) { + res = dir_rewind(dj); + } else { + res = dir_read(dj, dir); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, dir, fno); /* Get the object information */ + res = dir_next(dj); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + } + } + + return res; +} + +#endif /* _USE_DIR */ + diff --git a/source-1.0L-F11/AVR/bootldr/bootldr/pff.h b/source-1.0L-F11/AVR/bootldr/bootldr/pff.h new file mode 100755 index 0000000..c6e4d04 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/bootldr/pff.h @@ -0,0 +1,192 @@ +/*---------------------------------------------------------------------------/ +/ Petit FatFs - FAT file system module include file R0.02a (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ Petit FatFs module is an open source software to implement FAT file system to +/ small embedded systems. This is a free software and is opened for education, +/ research and commercial developments under license policy of following trems. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The Petit FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#include "integer.h" + +/*---------------------------------------------------------------------------/ +/ Petit FatFs Configuration Options +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FATFS +#define _FATFS + +#define _USE_READ 1 /* 1:Enable pf_read() */ + +#define _USE_DIR 0 /* 1:Enable pf_opendir() and pf_readdir() */ + +#define _USE_LSEEK 0 /* 1:Enable pf_lseek() */ + +#define _USE_WRITE 0 /* 1:Enable pf_write() */ + +#define _FS_FAT12 0 /* 1:Enable FAT12 support */ +#define _FS_FAT32 1 /* 1:Enable FAT32 support */ + + +#define _CODE_PAGE 1 +/* Defines which code page is used for path name. Supported code pages are: +/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866, +/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only). +/ SBCS code pages except for 1 requiers a case conversion table. This +/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */ + + +#define _WORD_ACCESS 1 +/* The _WORD_ACCESS option defines which access method is used to the word +/ data in the FAT structure. +/ +/ 0: Byte-by-byte access. Always compatible with all platforms. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned +/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code efficiency. */ + + +/* End of configuration options. Do not change followings without care. */ +/*--------------------------------------------------------------------------*/ + + + +#if _FS_FAT32 +#define CLUST DWORD +#else +#define CLUST WORD +#endif + + +/* File system object structure */ + +typedef struct { + BYTE fs_type; /* FAT sub type */ + BYTE flag; /* File status flags */ + BYTE csize; /* Number of sectors per cluster */ + BYTE pad1; + WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */ + CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */ + DWORD database; /* Data start sector */ + DWORD fptr; /* File R/W pointer */ + DWORD fsize; /* File size */ + CLUST org_clust; /* File start cluster */ + CLUST curr_clust; /* File current cluster */ + DWORD dsect; /* File current data sector */ +} FATFS; + + + +/* Directory object structure */ + +typedef struct { + WORD index; /* Current read/write index number */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ + CLUST sclust; /* Table start cluster (0:Static table) */ + CLUST clust; /* Current cluster */ + DWORD sect; /* Current sector */ +} DIR; + + + +/* File status structure */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + char fname[13]; /* File name */ +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* 0 */ + FR_DISK_ERR, /* 1 */ + FR_NOT_READY, /* 2 */ + FR_NO_FILE, /* 3 */ + FR_NO_PATH, /* 4 */ + FR_NOT_OPENED, /* 5 */ + FR_NOT_ENABLED, /* 6 */ + FR_NO_FILESYSTEM /* 7 */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* Petit FatFs module application interface */ + +FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */ +FRESULT pf_open (const char*); /* Open a file */ +FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */ +FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */ +FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */ +FRESULT pf_opendir (DIR*, const char*); /* Open a directory */ +FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */ + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + +/* File status flag (FATFS.flag) */ + +#define FA_OPENED 0x01 +#define FA_WPRT 0x02 +#define FA__WIP 0x40 + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + + +#endif /* _FATFS */ diff --git a/source-1.0L-F11/AVR/bootldr/how to configure bootloader.txt b/source-1.0L-F11/AVR/bootldr/how to configure bootloader.txt new file mode 100755 index 0000000..f233898 --- /dev/null +++ b/source-1.0L-F11/AVR/bootldr/how to configure bootloader.txt @@ -0,0 +1,32 @@ +1. In the application project, modify the "memory settings" linker option. In the FLASH segment add: + .bootldrinfo=0xF7FC (for atmega with 128K Flash), or + .bootldrinfo=0x37FC (for atmega with 32K Flash) + It should be 8 bytes (4 words) before the start of the bootloader area. + +2. Change the application version number as desired. + +3. Rebuild the application to generate a new .hex file + +4. In the bootloader project, modify the "memory settings" linker option. In the FLASH segment add: + .text=0xF800 (for atmega with 128K Flash), or + .text=0x3800 (for atmega with 32K Flash) + It should be the start of the bootloader area in words. These numbers assume a 4K bootloader. + +5. Modify the "Symbols" compiler and assembler options. Change + .text=0x1F000 (for atmega with 128K Flash), or + .text=0x7000 (for atmega with 32K Flash) + It should be the start of the bootloader area in bytes. These numbers assume a 4K bootloader. + +6. Rebuild the bootloader project to generate a new .hex file + +7. Append the bootloader to the application .hex file. You can do this in a text editor, after + deleting the line :00000001FF at the end of the application section, or using srec_cat: + srec_cat application.hex -intel bootloader.hex -intel -o merged.hex -intel + +8. Program the merged .hex file to the board, just like you would for any other .hex + +9. Connect to the board with the ISP programmer. Set the BOOTSZ fuse to 2048W (for 4K bootloader) + and BOOTRST fuse to on/true. + +10. To generate the .bin file used by the bootloader to flash new code updates, use + avr-objcopy -O binary -R .eeprom -R .fuse -R .lock -R .signature application.elf application.bin \ No newline at end of file diff --git a/source-1.0L-F11/AVR/cardtest.cpp b/source-1.0L-F11/AVR/cardtest.cpp new file mode 100755 index 0000000..5ff049f --- /dev/null +++ b/source-1.0L-F11/AVR/cardtest.cpp @@ -0,0 +1,216 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "portmacros.h" +#include "noklcd.h" +#include "millitimer.h" +#include "SdFat.h" +#include "SdBaseFile.h" +#include "micro.h" +#include "ports.h" +#include "diskmenu.h" +#include "cardtest.h" + +// work-around for compiler bug +#undef PROGMEM +#define PROGMEM __attribute__(( section(".progmem.data") )) +#undef PSTR +#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];})) + +#define STATUS_LED_PORT B +#define STATUS_LED_PIN 3 + +#define TEXTBUF_SIZE 22 +extern char textBuf[]; +extern uint8_t sectorBuf[512]; + +void CardTest() +{ + LcdClear(); + + SdFat sd; + if (!sd.init(SPI_HALF_SPEED)) + { + snprintf(textBuf, TEXTBUF_SIZE, "SD card error %d:%d", sd.card()->errorCode(), sd.card()->errorData()); + LcdGoto(0,0); + LcdTinyString(textBuf, TEXT_NORMAL); + while(1); + } + + cid_t cid; + + uint32_t cardSize = sd.card()->cardSize(); + cardSize /= (2L*1024L); + + sd.card()->readCID(&cid); + + snprintf(textBuf, TEXTBUF_SIZE, "CID %d %c%c%c%c%c %lu MB", cid.mid, cid.pnm[0], cid.pnm[1], cid.pnm[2], cid.pnm[3], cid.pnm[4], cardSize); + LcdGoto(0,0); + LcdTinyString(textBuf, TEXT_NORMAL); + + csd_t csd; + sd.card()->readCSD(&csd); + + uint8_t writeBlockPow; // write block length, log2 + uint8_t sectorSizeCnt; // minimum erasable size, in write blocks + + if (csd.v1.csd_ver == 1) + { + csd1_t* c = &csd.v1; + + writeBlockPow = 4*c->write_bl_len_high + c->write_bl_len_low; + sectorSizeCnt = 2*c->sector_size_high + c->sector_size_low; + } + else + { + csd2_t* c = &csd.v2; + + writeBlockPow = 4*c->write_bl_len_high + c->write_bl_len_low; + sectorSizeCnt = 2*c->sector_size_high + c->sector_size_low; + } + + sectorSizeCnt += 1; // these all seem to be 2**n - 1? + + uint32_t writeBlock=1; + for (uint8_t i=0; ireadBlock(imageFirstBlock + b, sectorBuf)) + { + LcdGoto(0,2); + LcdTinyStringP(PSTR("SD read error"), TEXT_NORMAL); + while(1); + } + + // alter the data, to prevent any kind of compression/optimization on the card + for (uint16_t i=0; i<512; i++) + { + sectorBuf[i] ^= sectorBuf[i+1]; + } + + // blink the LED + if ((writeCount & 0x7) == 0) + PORT(STATUS_LED_PORT) ^= (1<writeBlock(imageFirstBlock + b, sectorBuf)) + { + LcdGoto(0,2); + LcdTinyStringP(PSTR("SD write error"), TEXT_NORMAL); + while(1); + } + + uint32_t writeTime = millis() - t0; + + // update stats + writeCount++; + writeTotalTime += writeTime; + if (writeTime > 20) + above20Count++; + if (writeTime > worstTime) + worstTime = writeTime; + + // pseudo-interleave + if ((cnt & 1) == 0) + b += 6; + else + b -= 5; + + _delay_ms(3); + } + } + + uint32_t avg = (writeTotalTime + (writeCount >> 1))/ writeCount; + + LcdGoto(0,2); + LcdTinyStringP(PSTR("AVG.ms/MAX.ms/LONG.%"), TEXT_NORMAL); + + snprintf(textBuf, TEXTBUF_SIZE, "512B RRWI %lu/%lu/%lu", avg, worstTime, above20Count*100/writeCount); + LcdGoto(0,3); + LcdTinyString(textBuf, TEXT_NORMAL); + + // Card: actual capacity, block size, erase size, best test result (random read-write interleaved) average/max/percent "long" over 20ms + // ---------------------------------------------------------- + // PNY class 10 8GB: 7708 MB, 512B block, 64K erase. 512B RRWI 10/189/1 (random read-write interleave) + // SanDisk unrated Ultra II 2GB: 1938 MB, 1024B block, 32K erase. 512B RRWI 7/79/0 + // Transcend unrated 2GB: 1875 MB, 1024B block, 128K erase. 512B RRWI 3/103/0 + // SanDisk unrated 128MB: 120 MB, 512B block, 16K erase. 512B RRWI 5/94/1 + + // enabling the TACH stuff seems to cause some cards to get errors during this test. Coupling between traces? Why doesn't it happen during normal operation? + + // Transcend unrated 2GB: Finder consistently "goes to sleep" after copying first 19 tracks, but worked twice after 3 tries. Maybe it's too fast? + + + + while(1); +} \ No newline at end of file diff --git a/source-1.0L-F11/AVR/cardtest.h b/source-1.0L-F11/AVR/cardtest.h new file mode 100755 index 0000000..6f1b87e --- /dev/null +++ b/source-1.0L-F11/AVR/cardtest.h @@ -0,0 +1,21 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#ifndef CARDTEST_H_ +#define CARDTEST_H_ + +void CardTest(); + + + +#endif /* CARDTEST_H_ */ \ No newline at end of file diff --git a/source-1.0L-F11/AVR/diskmenu.cpp b/source-1.0L-F11/AVR/diskmenu.cpp new file mode 100755 index 0000000..046b09a --- /dev/null +++ b/source-1.0L-F11/AVR/diskmenu.cpp @@ -0,0 +1,368 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "diskmenu.h" +#include "SdFat.h" +#include "SdBaseFile.h" +#include "noklcd.h" + +#define SECTORBUF_SIZE (23 * 512) // use the 24th buffer for directory breadcrumbs +extern uint8_t sectorBuf[24][512]; +extern uint8_t extraBuf[512]; + +typedef struct FileEntry +{ + char longName[FILENAME_LEN+1]; + char shortName[SHORTFILENAME_LEN+1]; + eImageType imageFileType; +} FileEntry; + +bool dirLfnNext(SdFat& sd, dir_t& dir, char* lfn) +{ + uint8_t offset[] = {1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30}; + uint8_t lfnIn = 130; + uint8_t i; + uint8_t ndir=0; + uint8_t sum; + uint8_t test=0; + bool haveLong = false; + + while( sd.vwd()->read( &dir, 32 ) == 32 ) + { + if( DIR_IS_LONG_NAME( &dir ) ) + { + if( ! haveLong ) + { + if(( dir.name[0] & 0XE0 ) != 0X40 ) + continue; + ndir = dir.name[0] & 0X1F; + test = dir.creationTimeTenths; + haveLong = true; + lfnIn = 130; + lfn[ lfnIn ] = 0; + } + else if( dir.name[0] != --ndir || test != dir.creationTimeTenths ) + { + haveLong = false; + continue; + } + char *p = (char*) & dir; + if( lfnIn > 0 ) + { + lfnIn -= 13; + for( i = 0; i < 13; i++ ) + lfn[lfnIn + i] = p[offset[i]]; + } + } + else if( DIR_IS_FILE_OR_SUBDIR( &dir ) + && dir.name[0] != DIR_NAME_DELETED + && dir.name[0] != DIR_NAME_FREE + && dir.name[0] != '.') + { + if( haveLong ) + { + for( sum = i = 0; i < 11; i++ ) + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + dir.name[i]; + if( sum != test || ndir != 1 ) + haveLong = false; + } + if( haveLong ) + { + for( i = 0; lfnIn + i <= 130 ; i++ ) + lfn[i] = lfn[lfnIn + i]; + return true; + } + // else if( dir.reservedNT ) + // return "Reserved NT"; + else + { + SdBaseFile::dirName( dir, lfn ); + return true; + } + } + else + { + if( dir.name[0] == DIR_NAME_FREE ) + break; + haveLong = false; + } + } + lfn[ 0 ] = 0; + return false; +} + +eImageType DiskImageFileType(dir_t& dir, const char *filename) +{ + if (filename[0] == '.') + return DISK_IMAGE_NONE; + + if (DIR_IS_SUBDIR(&dir)) + return DISK_IMAGE_DIRECTORY; + + if (!DIR_IS_FILE(&dir)) + return DISK_IMAGE_NONE; + + uint32_t size = dir.fileSize; + + if (size == (unsigned long)1024 * 400) + return DISK_IMAGE_400K; + else if (size == (unsigned long)1024 * 800) + return DISK_IMAGE_800K; + else if (size == (unsigned long)1024 * 1440) + return DISK_IMAGE_1440K; + else if (size > (unsigned long)1024 * 400 && + size < (unsigned long)1024 * 1500) + { + // get the 8.3 filename + char shortName[SHORTFILENAME_LEN+1]; + SdBaseFile::dirName(dir, shortName); + + // read the first sector of the file + SdBaseFile f; + if (f.open(shortName, O_RDONLY)) + { + f.read(extraBuf, 512); + f.close(); + + // is it a DiskCopy 4.2 image? + if (extraBuf[0x52] == 0x01 && + extraBuf[0x53] == 0x00) + { + size = ((unsigned long)extraBuf[0x41] * 65536 + (unsigned long)extraBuf[0x42] * 256 + (unsigned long)extraBuf[0x43]) / 1024; + + if (size == 400) + return DISK_IMAGE_DISKCOPY_400K; + else if (size == 800) + return DISK_IMAGE_DISKCOPY_800K; + else if (size == 1440) + return DISK_IMAGE_DISKCOPY_1440K; + } + } + } + + return DISK_IMAGE_NONE; +} + +uint16_t diskMenuEntryCount; +uint16_t diskMenuOffset = 0; +uint16_t diskMenuSelection = 0; +char selectedFile[FILENAME_LEN+1]; +char selectedLongFile[FILENAME_LEN+1]; +eImageType selectedFileType; +uint8_t subdirDepth = 0; + +#define LONGFILENAME_LEN 130 + +void InitDiskMenu(SdFat& sd) +{ + dir_t dir; + char name[LONGFILENAME_LEN+1]; + + diskMenuEntryCount = 0; + + // use the sector buffers to hold the filenames + uint16_t maxEntries = SECTORBUF_SIZE / sizeof(FileEntry); + FileEntry* pFileEntries = (FileEntry*)sectorBuf; + + sd.vwd()->rewind(); + while (dirLfnNext(sd, dir, name) && diskMenuEntryCount < maxEntries) + { + eImageType imageType; + + if ((imageType = DiskImageFileType(dir, name)) != DISK_IMAGE_NONE) + { + strncpy(pFileEntries[diskMenuEntryCount].longName, name, FILENAME_LEN+1); + SdBaseFile::dirName(dir, pFileEntries[diskMenuEntryCount].shortName); + pFileEntries[diskMenuEntryCount].imageFileType = imageType; + diskMenuEntryCount++; + } + } + + // add up directory, if not at the root + if (!sd.vwd()->isRoot()) + { + strncpy(pFileEntries[diskMenuEntryCount].longName, "..", FILENAME_LEN+1); + strncpy(pFileEntries[diskMenuEntryCount].shortName, "..", SHORTFILENAME_LEN+1); + pFileEntries[diskMenuEntryCount].imageFileType = DISK_IMAGE_UP_DIRECTORY; + diskMenuEntryCount++; + } + + char file1[FILENAME_LEN+1], file2[FILENAME_LEN+1], temp[FILENAME_LEN+1]; + eImageType tempType; + + // sort the names by longname + for (uint16_t i=0; i file2, swap them + if (diff > 0) + { + strncpy(temp, pFileEntries[i].longName, FILENAME_LEN+1); + strncpy(pFileEntries[i].longName, pFileEntries[j].longName, FILENAME_LEN+1); + strncpy(pFileEntries[j].longName, temp, FILENAME_LEN+1); + + strncpy(temp, pFileEntries[i].shortName, SHORTFILENAME_LEN+1); + strncpy(pFileEntries[i].shortName, pFileEntries[j].shortName, SHORTFILENAME_LEN+1); + strncpy(pFileEntries[j].shortName, temp, SHORTFILENAME_LEN+1); + + tempType = pFileEntries[i].imageFileType; + pFileEntries[i].imageFileType = pFileEntries[j].imageFileType; + pFileEntries[j].imageFileType = tempType; + } + } + } +} + +void DrawDiskMenu(SdFat& sd) +{ + // scroll menu if necessary + if (diskMenuSelection < diskMenuOffset) + diskMenuOffset = diskMenuSelection; + if (diskMenuSelection > diskMenuOffset+4) + diskMenuOffset = diskMenuSelection-4; + + LcdGoto(0,0); + LcdWrite(LCD_DATA, 0x7F); + for (int i=0; i<19; i++) + LcdWrite(LCD_DATA, 0x40); + + LcdTinyStringFramed("Select Disk"); + + for (int i=0; i<19; i++) + LcdWrite(LCD_DATA, 0x40); + LcdWrite(LCD_DATA, 0x7F); + + if (diskMenuEntryCount == 0) + { + LcdGoto(0, 1); + LcdTinyString("no image files found", TEXT_NORMAL); + } + else + { + FileEntry* pFileEntries = (FileEntry*)sectorBuf; + + int row = 0; + for (uint16_t i=diskMenuOffset; i= barStart && y <= barEnd) + b = 0x80 | (b >> 1); + else + b = (b >> 1); + } + + LcdWrite(LCD_DATA, b); + } + } + + // prevent moving selection past end of list + if (diskMenuSelection >= diskMenuOffset + row) + { + diskMenuSelection = diskMenuOffset + row - 1; + if (row == 4 && diskMenuOffset > 0) + { + diskMenuOffset--; // scroll backwards + } + DrawDiskMenu(sd); // draw again + } + } +} diff --git a/source-1.0L-F11/AVR/diskmenu.h b/source-1.0L-F11/AVR/diskmenu.h new file mode 100755 index 0000000..3a856e4 --- /dev/null +++ b/source-1.0L-F11/AVR/diskmenu.h @@ -0,0 +1,45 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#ifndef DISKMENU_H_ +#define DISKMENU_H_ + +#include + +typedef enum { + DISK_IMAGE_NONE = 0, + DISK_IMAGE_DIRECTORY, + DISK_IMAGE_UP_DIRECTORY, + DISK_IMAGE_400K, + DISK_IMAGE_800K, + DISK_IMAGE_1440K, + DISK_IMAGE_DISKCOPY_400K, + DISK_IMAGE_DISKCOPY_800K, + DISK_IMAGE_DISKCOPY_1440K +} eImageType; + +#define FILENAME_LEN 21 +#define SHORTFILENAME_LEN 12 // 8.3 + +extern uint16_t diskMenuSelection; +extern char selectedFile[]; +extern char selectedLongFile[]; +extern eImageType selectedFileType; +extern uint8_t subdirDepth; + +class SdFat; + +void InitDiskMenu(SdFat& sd); +void DrawDiskMenu(SdFat& sd); + +#endif /* DISKMENU_H_ */ diff --git a/source-1.0L-F11/AVR/floppyemu.atsln b/source-1.0L-F11/AVR/floppyemu.atsln new file mode 100755 index 0000000..6c08408 --- /dev/null +++ b/source-1.0L-F11/AVR/floppyemu.atsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# AvrStudio Solution File, Format Version 11.00 +Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "floppyemu", "floppyemu.cppproj", "{E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Debug|AVR.ActiveCfg = Debug|AVR + {E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Debug|AVR.Build.0 = Debug|AVR + {E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Release|AVR.ActiveCfg = Release|AVR + {E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/source-1.0L-F11/AVR/floppyemu.atsuo b/source-1.0L-F11/AVR/floppyemu.atsuo new file mode 100755 index 0000000..1d0c979 Binary files /dev/null and b/source-1.0L-F11/AVR/floppyemu.atsuo differ diff --git a/source-1.0L-F11/AVR/floppyemu.cpp b/source-1.0L-F11/AVR/floppyemu.cpp new file mode 100755 index 0000000..22474dd --- /dev/null +++ b/source-1.0L-F11/AVR/floppyemu.cpp @@ -0,0 +1,2017 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "portmacros.h" +#include "noklcd.h" +#include "millitimer.h" +#include "SdFat.h" +#include "SdBaseFile.h" +#include "micro.h" +#include "ports.h" +#include "diskmenu.h" + +// work-around for compiler bug +#undef PROGMEM +#define PROGMEM __attribute__(( section(".progmem.data") )) +#undef PSTR +#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];})) + +// I/O pin assignments +#define CPLD_RESET_PORT B +#define CPLD_RESET_PIN 0 + +#define CPLD_STEP_DIR_MOTOR_ON_PORT C +#define CPLD_STEP_DIR_MOTOR_ON_PIN 7 + +#define CPLD_STEP_REQ_PORT D +#define CPLD_STEP_REQ_PIN 0 // PCINT24 +#define CPLD_STEP_REQ_INT_MSK PCMSK3 +#define CPLD_STEP_REQ_INT_PIN PCINT24 +#define CPLD_STEP_REQ_INT_ENABLE PCIE3 + +#define CPLD_CURRENT_SIDE_PORT C +#define CPLD_CURRENT_SIDE_PIN 1 // PCINT17 +#define CPLD_CURRENT_SIDE_INT_MSK PCMSK2 +#define CPLD_CURRENT_SIDE_INT_PIN PCINT17 +#define CPLD_CURRENT_SIDE_INT_ENABLE PCIE2 + +#define CPLD_EJECT_REQ_PORT D +#define CPLD_EJECT_REQ_PIN 3 + +#define CPLD_STEP_ACK_DISK_IN_PORT C +#define CPLD_STEP_ACK_DISK_IN_PIN 2 + +#define CPLD_WR_REQ_PORT C +#define CPLD_WR_REQ_PIN 0 // PCINT16 +#define CPLD_WR_REQ_INT_MSK PCMSK2 +#define CPLD_WR_REQ_INT_PIN PCINT16 +#define CPLD_WR_REQ_INT_ENABLE PCIE2 + +#define CPLD_RD_READY_TK0_PORT C +#define CPLD_RD_READY_TK0_PIN 5 + +#define CPLD_RD_ACK_WR_TICK_PORT A +#define CPLD_RD_ACK_WR_TICK_PIN 7 // PCINT7 +#define CPLD_RD_ACK_WR_TICK_INT_MSK PCMSK0 +#define CPLD_RD_ACK_WR_TICK_INT_PIN PCINT7 +#define CPLD_RD_ACK_WR_TICK_INT_ENABLE PCIE0 + +#define CPLD_DATA_PORT A + +#define CPLD_DATA_HIZ_PORT C +#define CPLD_DATA_HIZ_PIN 6 + +#define CPLD_TACH_PORT D +#define CPLD_TACH_PIN 5 + +#define CPLD_TMS_PORT C +#define CPLD_TMS_PIN 3 + +#define SELECT_BUTTON_PORT D +#define SELECT_BUTTON_PIN 4 + +#define PREV_BUTTON_PORT D +#define PREV_BUTTON_PIN 1 + +#define NEXT_BUTTON_PORT D +#define NEXT_BUTTON_PIN 2 + +#define STATUS_LED_PORT B +#define STATUS_LED_PIN 3 + +#define CARD_WPROT_PORT D +#define CARD_WPROT_PIN 7 + +#define SECTOR_DATA_SIZE 512 +#define INTER_SECTOR_GAP_SIZE 55 +#define ADDRESS_DATA_GAP_SIZE 10 +#define SECTOR_DATA_HEADER_SIZE 3 +#define SECTOR_DATA_SECTORNUM_START SECTOR_DATA_HEADER_SIZE +#define SECTOR_DATA_SECTORNUM_SIZE 1 +#define SECTOR_DATA_ENCODED_TAGS_START (SECTOR_DATA_HEADER_SIZE+SECTOR_DATA_SECTORNUM_SIZE) +#define SECTOR_DATA_ENCODED_TAGS_SIZE 16 +#define SECTOR_DATA_ENCODED_DATA_START (SECTOR_DATA_HEADER_SIZE+SECTOR_DATA_SECTORNUM_SIZE+SECTOR_DATA_ENCODED_TAGS_SIZE) +#define SECTOR_DATA_ENCODED_DATA_SIZE 683 +#define SECTOR_DATA_CHECKSUM_START (SECTOR_DATA_ENCODED_DATA_START+SECTOR_DATA_ENCODED_DATA_SIZE) + +// 8 byte marker placed at the end of the program binary, used by the bootloader. +// Configure the .bootldrinfo address to be 8 bytes below the bootloader start address for the type of Atmega being used. +#define DEVICEID_HIGH 0xDDDD +#define DEVICEID_LOW 0xDDDD +#define VERSIONID 0x0100 +const uint16_t bootloader_info[] __attribute__(( section(".bootldrinfo") )) = { DEVICEID_HIGH, DEVICEID_LOW, VERSIONID, 0x0000 }; + +const char versionStr[] PROGMEM = "App Version 1.0 L"; + +volatile uint8_t currentTrack; +volatile uint8_t prevTrack; +volatile uint8_t currentSide; +volatile uint8_t prevSide; +volatile uint8_t writeMode; +volatile bool restartDisk; +volatile bool writeError; + +bool diskInserted; +bool readOnly; +bool mfmMode; +uint16_t crc; +uint8_t numberOfDiskSides; +uint8_t currentSector; +uint16_t driveTachHalfPeriod; +uint8_t tachFlutter; + +uint8_t writeDisplayTimer; +uint8_t cpldFirmwareVersion; + +#define TEXTBUF_SIZE 22 +char textBuf[TEXTBUF_SIZE]; + +#define NUM_BUFFERS 24 +uint8_t sectorBuf[NUM_BUFFERS][SECTOR_DATA_SIZE]; +uint8_t extraBuf[SECTOR_DATA_SIZE]; + +bool selectedFileIsDiskCopyFormat; + +extern const uint16_t sony_track_start[] PROGMEM; +const uint16_t sony_track_start[80] = { + 0, 12, 24, 36, 48, 60 , 72, 84, + 96, 108, 120, 132, 144, 156, 168, 180, + + 192, 203, 214, 225, 236, 247, 258, 269, + 280, 291, 302, 313, 324, 335, 346, 357, + + 368, 378, 388, 398, 408, 418, 428, 438, + 448, 458, 468, 478, 488, 498, 508, 518, + + 528, 537, 546, 555, 564, 573, 582, 591, + 600, 609, 618, 627, 636, 645, 654, 663, + + 672, 680, 688, 696, 704, 712, 720, 728, + 736, 744, 752, 760, 768, 776, 784, 792 +}; + +extern const uint8_t sony_track_len[] PROGMEM; +const uint8_t sony_track_len[80] = { + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 +}; + +extern const uint8_t sony_to_disk_byte[] PROGMEM; +const uint8_t sony_to_disk_byte[] = { + 0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, /* 0x00 */ + 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC, /* 0x10 */ + 0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3, + 0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, /* 0x20 */ + 0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, + 0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, /* 0x30 */ + 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + +extern const uint8_t disk_byte_to_sony[] PROGMEM; +const uint8_t disk_byte_to_sony[] = { + /* table begins at disk byte 0x96, value of 0xFF is an invalid disk byte */ + /* 0x96 */ 0x00, 0x01, 0xFF, 0xFF, 0x02, 0x03, 0xFF, 0x04, + /* 0x9E */ 0x05, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* 0xA6 */ 0x07, 0x08, 0xFF, 0xFF, 0xFF, 0x09, 0x0A, 0x0B, + /* 0xAE */ 0x0C, 0x0D, 0xFF, 0xFF, 0x0E, 0x0F, 0x10, 0x11, + /* 0xB6 */ 0x12, 0x13, 0xFF, 0x14, 0x15, 0x16, 0x17, 0x18, + /* 0xBE */ 0x19, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* 0xC6 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0xFF, 0x1C, + /* 0xCE */ 0x1D, 0x1E, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, + /* 0xD6 */ 0x20, 0x21, 0xFF, 0x22, 0x23, 0x24, 0x25, 0x26, + /* 0xDE */ 0x27, 0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x29, + /* 0xE6 */ 0x2A, 0x2B, 0xFF, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + /* 0xEE */ 0x31, 0x32, 0xFF, 0xFF, 0x33, 0x34, 0x35, 0x36, + /* 0xF6 */ 0x37, 0x38, 0xFF, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, + /* 0xFE */ 0x3E, 0x3F +}; + +uint8_t sectorDataHeaderGCR[] = { 0xD5, 0xAA, 0xAD }; + +extern const uint16_t crc_ccitt[] PROGMEM; +const uint16_t crc_ccitt[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + +void ResetDiskState(); + +uint16_t writeErrorNumber; + +void error(const char* msg) +{ + bool wasWriteError = writeError; + uint16_t wasWriteErrorNumber = writeErrorNumber; + + ResetDiskState(); // clears writeError and writeErrorNumber + + LcdClear(); + LcdGoto(0,0); + if (wasWriteError) + LcdTinyStringP(PSTR("WRITE ERROR "), TEXT_INVERSE); + else + LcdTinyStringP(PSTR("FATAL ERROR "), TEXT_INVERSE); + LcdGoto(0,1); + LcdTinyString(msg, TEXT_NORMAL); + + if (wasWriteError) + { + snprintf(textBuf, TEXTBUF_SIZE, "%u", wasWriteErrorNumber); + LcdGoto(0,5); + LcdTinyString(textBuf, TEXT_NORMAL); + } + + while (1); +} + +void InitPorts() +{ + // set all data lines as outputs, MSB (RD_ACK/WR_TICK) as input + DDR(CPLD_DATA_PORT) = 0x7F; + + // initialize the other output lines + DDR(CPLD_TACH_PORT) |= (1<> 4; + if (speedZone > 4) + speedZone = 4; + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + driveTachHalfPeriod = F_CPU / (2 * zoneRPM[speedZone]); + // OCR1A update will be performed during the next sector 0 read + } + + TIFR1 = (1 << OCF1A); // Clear the timer 1 compare A match flag. Not sure this is actually necessary. +} + +uint16_t trackStart(uint8_t trackNumber) +{ + return mfmMode ? trackNumber * 18 : pgm_read_word(&sony_track_start[trackNumber]); +} + +uint8_t trackLength(uint8_t trackNumber) +{ + return mfmMode ? 18 : pgm_read_byte(&sony_track_len[trackNumber]); +} + +#define BUFFER_DIRTY 1 +#define BUFFER_DATA_VALID 2 +#define BUFFER_LOCKED 4 + +volatile uint8_t bufferState[NUM_BUFFERS]; +volatile uint8_t wrTrack; +volatile uint8_t wrSide; +volatile uint8_t wrSector; + +// these variables are used only within the interrupt routine, and do not need to be declared volatile +uint8_t wrTick; +uint16_t writeCount; +uint8_t writeTemp; +uint8_t currentWriteBufferNumber; +uint8_t ck5, ck6, ck7; +uint8_t XBit; +uint8_t* pSectorBuf; + +void WriteError() +{ + writeMode = false; + restartDisk = true; + writeError = true; + writeCount = 0; +} + +// pin state change interrupt: STEP +ISR(PCINT3_vect) +{ + // step to a new track? + if (bit_is_set(PIN(CPLD_STEP_REQ_PORT), CPLD_STEP_REQ_PIN)) + { + // determine the range of dirty sector buffers + uint8_t trackLen = trackLength(currentTrack); + uint8_t firstDirtyBuffer = NUM_BUFFERS, lastDirtyBuffer=0; + + for (uint8_t i=0; i= SECTOR_DATA_SECTORNUM_START) + { + strncpy(textBuf, "incomplete write", TEXTBUF_SIZE); + writeErrorNumber = 1000 + writeCount; + WriteError(); + } + + restartDisk = true; + } +} + +// pin state change interrupt: SIDE, WR_REQ +ISR(PCINT2_vect) +{ + // did the current side change? + uint8_t newSide = ((PIN(CPLD_CURRENT_SIDE_PORT) >> CPLD_CURRENT_SIDE_PIN) & 0x01); + if (newSide != currentSide) + { + if (numberOfDiskSides == 2) + currentSide = newSide; + else + currentSide = 0; + restartDisk = true; + + // premature end of a write? + if (writeCount >= SECTOR_DATA_SECTORNUM_START) + { + strncpy(textBuf, "incomplete write", TEXTBUF_SIZE); + writeErrorNumber = 2000 + writeCount; + WriteError(); + } + } + + // did the read/write mode change? RD_RW: 0 = write, 1 = read + uint8_t wreqBit = bit_is_clear(PIN(CPLD_WR_REQ_PORT), CPLD_WR_REQ_PIN); + if (wreqBit != writeMode) + { + writeMode = wreqBit; + + if (writeMode) + { + // switch the DATA pins to inputs + DDR(CPLD_DATA_PORT) = 0; + + // indicate that the data bus has been released + PORT(CPLD_DATA_HIZ_PORT) |= (1<= SECTOR_DATA_SECTORNUM_START) + { + strncpy(textBuf, "incomplete write", TEXTBUF_SIZE); + writeErrorNumber = 3000 + writeCount; + WriteError(); + } + } + + restartDisk = true; + } +} + +void HandleGCRWrite() +{ + uint8_t diskByte = 0x80 | PIN(CPLD_DATA_PORT); + + if (writeCount < SECTOR_DATA_ENCODED_TAGS_START) + { + // look for the sector header + // the final header byte is the sector number + if (writeCount == SECTOR_DATA_SECTORNUM_START) + { + uint8_t sector = pgm_read_byte(&disk_byte_to_sony[diskByte - 0x96]); + + if (sector >= trackLength(currentTrack)) + { + snprintf(textBuf, TEXTBUF_SIZE, "bad sector %d for t%d", sector, currentTrack); + writeErrorNumber = 60; + WriteError(); + } + + uint8_t trackLen = trackLength(currentTrack); + currentWriteBufferNumber = trackLen * currentSide + sector; + + if (bufferState[currentWriteBufferNumber] & BUFFER_LOCKED) + { + snprintf(textBuf, TEXTBUF_SIZE, "buf locked %d/%d:%d", currentTrack, currentSide, sector); + writeErrorNumber = 61; + WriteError(); + } + + pSectorBuf = sectorBuf[currentWriteBufferNumber]; + bufferState[currentWriteBufferNumber] |= BUFFER_LOCKED; + bufferState[currentWriteBufferNumber] &= ~BUFFER_DATA_VALID; + wrTrack = currentTrack; + wrSide = currentSide; + wrSector = sector; + + // turn on the LED when receiving a sector write + PORT(STATUS_LED_PORT) &= ~(1<> 7; + ck7 = (ck7 << 1) | XBit; + break; + + case 1: + b = (writeTemp & 0xC0) | dataIn; // A7 A6 0 0 0 0 0 0 | 0 0 A5 A4 A3 A2 A1 A0 + b ^= ck7; + + if (writeCount >= SECTOR_DATA_ENCODED_DATA_START) + *pSectorBuf++ = b; + + //ADDX(ck5, b); + addResult = (uint16_t)ck5 + b + XBit; + ck5 = addResult & 0xFF; + XBit = addResult >> 8; + writeTemp <<= 2; // B7 B6 C7 C6 0 0 0 0 + break; + + case 2: + b = (writeTemp & 0xC0) | dataIn; // B7 B6 0 0 0 0 0 0 | 0 0 B5 B4 B3 B2 B1 B0 + b ^= ck5; + + if (writeCount >= SECTOR_DATA_ENCODED_DATA_START) + *pSectorBuf++ = b; + + //ADDX(ck6, b); + addResult = (uint16_t)ck6 + b + XBit; + ck6 = addResult & 0xFF; + XBit = addResult >> 8; + writeTemp <<= 2; // C7 C6 0 0 0 0 0 0 + break; + + case 3: + b = writeTemp | dataIn; // C7 C6 0 0 0 0 0 0 | 0 0 C5 C4 C3 C2 C1 C0 + b ^= ck6; + + if (writeCount >= SECTOR_DATA_ENCODED_DATA_START) + *pSectorBuf++ = b; + + //ADDX(ck7, b); + addResult = (uint16_t)ck7 + b + XBit; + ck7 = addResult & 0xFF; + XBit = addResult >> 8; + break; + } + } + else + { + // verify the checksum + if (writeCount == SECTOR_DATA_CHECKSUM_START) + { + writeTemp = dataIn; + writeTemp <<= 2; + } + else if (writeCount == SECTOR_DATA_CHECKSUM_START+1) + { + b = (writeTemp & 0xC0) | dataIn; + writeTemp <<= 2; + if (b != ck5) + { + strncpy(textBuf, "checksum failure 0", TEXTBUF_SIZE); + writeErrorNumber = 62; + WriteError(); + } + } + else if (writeCount == SECTOR_DATA_CHECKSUM_START+2) + { + b = (writeTemp & 0xC0) | dataIn; + writeTemp <<= 2; + if (b != ck6) + { + strncpy(textBuf, "checksum failure 1", TEXTBUF_SIZE); + writeErrorNumber = 63; + WriteError(); + } + } + else if (writeCount == SECTOR_DATA_CHECKSUM_START+3) + { + b = writeTemp | dataIn; + writeTemp <<= 2; + if (b != ck7) + { + strncpy(textBuf, "checksum failure 2", TEXTBUF_SIZE); + writeErrorNumber = 64; + WriteError(); + } + + // success! + bufferState[currentWriteBufferNumber] |= BUFFER_DATA_VALID; + bufferState[currentWriteBufferNumber] |= BUFFER_DIRTY; + bufferState[currentWriteBufferNumber] &= ~BUFFER_LOCKED; + + // turn off the LED at the end of a sector write + PORT(STATUS_LED_PORT) |= (1<> 8) ^ 0xA1]); + crc = (crc << 8) ^ pgm_read_word(&crc_ccitt[(uint8_t)(crc >> 8) ^ 0xA1]); + crc = (crc << 8) ^ pgm_read_word(&crc_ccitt[(uint8_t)(crc >> 8) ^ 0xA1]); + crc = (crc << 8) ^ pgm_read_word(&crc_ccitt[(uint8_t)(crc >> 8) ^ 0xFB]); + + for (uint16_t i=0; i> 8) ^ sectorBuf[bufferNumber][i]]); + } + + if (crc != receivedCRC) + { + strncpy(textBuf, "checksum fail", TEXTBUF_SIZE); + writeErrorNumber = 70; + WriteError(); + } +} + +// pin state change interrupt: WR_TICK +ISR(PCINT0_vect) +{ + uint8_t wrTickBit = bit_is_set(PIN(CPLD_RD_ACK_WR_TICK_PORT), CPLD_RD_ACK_WR_TICK_PIN); + + // was a new byte written? + if (writeMode && wrTickBit != wrTick) + { + wrTick = wrTickBit; + + if (!mfmMode) + { + HandleGCRWrite(); + } + else + { + if (wrTickBit == 0) + { + // high nibble arrives first + writeTemp = (PIN(CPLD_DATA_PORT) << 4) & 0xF0; + return; + } + else + { + writeTemp |= (PIN(CPLD_DATA_PORT) & 0x0F); + + if (writeCount == 2) + { + if (writeTemp == 0xFB) + { + writeCount++; + + // header received OK! + currentWriteBufferNumber = currentSector; // assume the buffer to write was the last one read + + if (bufferState[currentWriteBufferNumber] & BUFFER_LOCKED) + { + snprintf(textBuf, TEXTBUF_SIZE, "buf locked %d/%d:%d", currentTrack, currentSide, currentSector); + writeErrorNumber = 71; + WriteError(); + return; + } + + pSectorBuf = sectorBuf[currentWriteBufferNumber]; + bufferState[currentWriteBufferNumber] |= BUFFER_LOCKED; + bufferState[currentWriteBufferNumber] &= ~BUFFER_DATA_VALID; + wrTrack = currentTrack; + wrSide = currentSide; + wrSector = currentSector; // assume the buffer to write was the last one read + + // turn on the LED when receiving a sector write + PORT(STATUS_LED_PORT) &= ~(1<> 2) | ((__c1 & 0xC0) >> 4) | ((__c2 & 0xC0) >> 6)) + +// rotate left +#define rot_ck0(__ck0) \ + do { \ + __ck0 &= 0xFF; \ + __ck0 = (__ck0 << 1) | (__ck0 >> 7);\ + } while(0) + +// ADC __ckr, __in; __out = __in ^ __ckl +#define enc_byte(__in, __out, __ckl, __ckr) \ + do { \ + uint8_t __d = __in; \ + __ckr += __d; \ + __ckr += (__ckl & 0x100) >> 8; \ + __ckl &= 0xFF; \ + __out = __d ^ __ckl; \ + } while(0) + +#define SendByteAndCheckRestart(b) \ + do { \ + if (restartDisk) \ + goto restart; \ + SendByte(b); \ + } while(0) + +void SendMFMSync() +{ + // send A1 sync + + // SendByte + // TODO: what if an interrupt has switched the data port to an input? This will turn on pull-ups + PORT(CPLD_DATA_PORT) = 0x0A; // data in bits 3-0, sync flag in bit 4 + PORT(CPLD_RD_READY_TK0_PORT) |= (1<> 8) ^ 0xA1]); + + // SendByte + // TODO: what if an interrupt has switched the data port to an input? This will turn on pull-ups + PORT(CPLD_DATA_PORT) = 0x11; // data in bits 3-0, sync flag in bit 4 + PORT(CPLD_RD_READY_TK0_PORT) |= (1<> 4) & 0x0F; + + //if (restartDisk) + // return; + + // SendByte + // TODO: what if an interrupt has switched the data port to an input? This will turn on pull-ups + PORT(CPLD_DATA_PORT) = out; + PORT(CPLD_RD_READY_TK0_PORT) |= (1<> 8) ^ data]); + + //if (restartDisk) + // return; + + // SendByte + // TODO: what if an interrupt has switched the data port to an input? This will turn on pull-ups + PORT(CPLD_DATA_PORT) = out; + PORT(CPLD_RD_READY_TK0_PORT) |= (1< 128) + lcd_vop--; + } + else if (bit_is_clear(PIN(SELECT_BUTTON_PORT), SELECT_BUTTON_PIN)) + { + eeprom_update_byte((uint8_t*)1, lcd_vop); + break; + } + + LcdWrite(LCD_CMD, 0x21); // LCD Extended Commands. + LcdWrite(LCD_CMD, lcd_vop); // Set LCD Vop (Contrast). + LcdWrite(LCD_CMD, 0x20); + } +} + +void PromptForFirmwareUpdate() +{ + LcdGoto(0,0); + LcdClear(); + LcdGoto(0,0); + LcdTinyStringP(PSTR("CPLD FIRMWARE UPDATE"), TEXT_NORMAL); + LcdGoto(0,2); + LcdTinyStringP(PSTR("Release buttons to"), TEXT_NORMAL); + LcdGoto(0,3); + LcdTinyStringP(PSTR("begin"), TEXT_NORMAL); + + // wait for the buttons to be released + while (bit_is_clear(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN) || + bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN) || + bit_is_clear(PIN(SELECT_BUTTON_PORT), SELECT_BUTTON_PIN)) + {} + + LcdGoto(0,2); + LcdTinyStringP(PSTR("NEXT: Load firmware"), TEXT_NORMAL); + LcdGoto(0,3); + LcdTinyStringP(PSTR("PREV: Cancel"), TEXT_NORMAL); + _delay_ms(400); + + // wait for a button press + while (bit_is_set(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN) && + bit_is_set(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN) && + bit_is_set(PIN(SELECT_BUTTON_PORT),SELECT_BUTTON_PIN)) + {} + + if (bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN)) + { + UpdateFirmware(); + } + else + { + LcdClear(); + } +} + +uint32_t imageFirstBlock, imageLastBlock; + +bool OpenImageFile() +{ + LcdClear(); + LcdGoto(0,0); + LcdTinyString(selectedLongFile, TEXT_NORMAL); + + LcdGoto(0,1); + + // open the disk image file + // to-do: check if the file is read-only on the card + bool openOK = true; + if (!f.open(selectedFile, O_RDWR)) + { + if (f.open(selectedFile, O_RDONLY)) + { + // TODO: How do we tell the CPLD the disk is read-only? + readOnly = true; + } + else + { + LcdTinyStringP(PSTR("error opening image"), TEXT_NORMAL); + openOK = false; + } + } + else + { + if (selectedFileType == DISK_IMAGE_400K || selectedFileType == DISK_IMAGE_DISKCOPY_400K) + { + numberOfDiskSides = 1; + } + else + { + numberOfDiskSides = 2; + } + } + + // get address of file on SD + if (openOK && !f.contiguousRange(&imageFirstBlock, &imageLastBlock)) + { + LcdTinyStringP(PSTR("image not contiguous"), TEXT_NORMAL); + openOK = false; + } + + if (!openOK) + { + _delay_ms(4000); // wait 4 seconds + } + else + { + LcdGoto(0,1); + // show disk image type + switch (selectedFileType) + { + case DISK_IMAGE_400K: + LcdTinyStringP(PSTR("400K raw image"), TEXT_NORMAL); + break; + + case DISK_IMAGE_800K: + LcdTinyStringP(PSTR("800K raw image"), TEXT_NORMAL); + break; + + case DISK_IMAGE_1440K: + LcdTinyStringP(PSTR("1440K raw image"), TEXT_NORMAL); + mfmMode = true; + break; + + case DISK_IMAGE_DISKCOPY_400K: + LcdTinyStringP(PSTR("400K DiskCopy image"), TEXT_NORMAL); + break; + + case DISK_IMAGE_DISKCOPY_800K: + LcdTinyStringP(PSTR("800K DiskCopy image"), TEXT_NORMAL); + break; + + case DISK_IMAGE_DISKCOPY_1440K: + LcdTinyStringP(PSTR("1440K DiskCopy image"), TEXT_NORMAL); + mfmMode = true; + break; + + default: + break; + } + + selectedFileIsDiskCopyFormat = (selectedFileType >= DISK_IMAGE_DISKCOPY_400K); + + if (bit_is_set(PIN(CARD_WPROT_PORT), CARD_WPROT_PIN)) + readOnly = true; + + // mount DiskCopy images read-only + if (selectedFileIsDiskCopyFormat) + readOnly = true; + + uint16_t volumeNameOffset = selectedFileIsDiskCopyFormat ? 0x424 + 0x54 : 0x424; + f.seekSet(volumeNameOffset); // offset of the Macintosh disk name in the image file + f.read(§orBuf[0][0], SECTOR_DATA_SIZE); + int nameLen = sectorBuf[0][0]; + uint8_t* name = §orBuf[0][1]; + name[nameLen] = 0; + name[21] = 0; // in case nameLen was bogus, terminate the string after 21 chars, which is the longest displayable name on the LCD + LcdGoto(0,2); + LcdTinyString((char*)name, TEXT_NORMAL); + LcdGoto(0,4); + LcdTinyStringP(PSTR("Track Side"), TEXT_NORMAL); + + // show a lock icon if the disk image is mounted as read-only + if (readOnly) + { + LcdGoto(77,0); + LcdWrite(LCD_DATA, 0x00); + LcdWrite(LCD_DATA, 0x78); + LcdWrite(LCD_DATA, 0x7E); + LcdWrite(LCD_DATA, 0x79); + LcdWrite(LCD_DATA, 0x79); + LcdWrite(LCD_DATA, 0x7E); + LcdWrite(LCD_DATA, 0x78); + } + } + + f.close(); + return openOK; +} + +void ResetDiskState() +{ + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + // useless code to prevent the "unused" bootloader_info array from being optimized away when optimizations are turned on + // there's probably a nicer way to accomplish this. + currentTrack = bootloader_info[currentTrack]; + + InitPorts(); + + currentTrack = 0; + prevTrack = 0; + restartDisk = false; + currentSide = 0; + prevSide = 0; + writeMode = 0; + diskInserted = false; + numberOfDiskSides = 2; + currentSector = 0; + readOnly = false; + mfmMode = false; + writeError = false; + writeDisplayTimer = 0; + tachFlutter = 0; + writeErrorNumber = 0; + writeCount = 0; + + for (uint8_t i=0; i= trackLen - 1) + return 0; + else + return prevSectorNumber + 1; + } + else + { + uint8_t halfTrackLen = (trackLen + 1) >> 1; + + // process sectors in interleaved order: + // 12 sector tracks: 0 6 1 7 2 8 3 9 4 10 5 11 + // 11 sector tracks: 0 6 1 7 2 8 3 9 4 10 5 + // 10 sector tracks: 0 5 1 6 2 7 3 8 4 9 + // 9 sector tracks: 0 5 1 6 2 7 3 8 4 + // 8 sector tracks: 0 4 1 5 2 6 3 7 + // This is how real floppies are formatted, and should improve read performance if the Mac + // can't completely process sector N before sector N+1 begins. It should also improve sector-by-sector + // write performance, because the Mac alternately reads (address header) and writes (data section) in + // this mode, and proper interleaving means it will read the desired address header sooner if the Mac + // isn't fast enough to process the sectors linearly (which it likely isn't). + if (prevSectorNumber > trackLen - 1 || + ((trackLen & 1) == 0 && prevSectorNumber == trackLen - 1) || + ((trackLen & 1) == 1 && prevSectorNumber == halfTrackLen - 1)) + return 0; + else if (prevSectorNumber < halfTrackLen) + return prevSectorNumber + halfTrackLen; + else + return prevSectorNumber + 1 - halfTrackLen; + } +} + +void ReadDiskCopy42Block(SdFat& sd, uint32_t blockToRead, uint8_t bufferNumber) +{ + // for a DiskCopy 4.2 image, read two blocks into a temp buffer, then copy the unaligned data into the sector buffer. + uint16_t i; + + if (!sd.card()->readStart(blockToRead)) + error("SD read start error"); + + // read part 1 + if (!sd.card()->readData(extraBuf)) + error("SD read error D"); + for (i=0; i<512-0x54; i++) + sectorBuf[bufferNumber][i] = extraBuf[0x54 + i]; + + // read part 2 + if (!sd.card()->readData(extraBuf)) + error("SD read error D"); + for (i=512-0x54; i<512; i++) + sectorBuf[bufferNumber][i] = extraBuf[0x54 + i - 512]; + + sd.card()->readStop(); +} + +void FlushDirtySectors(SdFat& sd, uint8_t trackNumber) +{ + uint8_t trackLen = trackLength(trackNumber); + uint8_t firstDirtyBuffer = NUM_BUFFERS, lastDirtyBuffer=0; + + // determine the dirty range + for (uint8_t i=0; ireadBlock(blockToRead, sectorBuf[i])) + error("SD read error W"); + } + } + + uint32_t firstBlockToWrite = imageFirstBlock + ((uint32_t)trackStart(trackNumber) * numberOfDiskSides + firstDirtyBuffer); + + if (mfmMode) + firstBlockToWrite += trackLen * wrSide; + + uint32_t numBuffersToWrite = lastDirtyBuffer + 1 - firstDirtyBuffer; + + if (!sd.card()->writeStart(firstBlockToWrite, numBuffersToWrite)) + error("SD writeStart fail"); + + for (uint8_t i=firstDirtyBuffer; i<=lastDirtyBuffer; i++) + { + if (!sd.card()->writeData(sectorBuf[i])) + error("SD write error"); + + bufferState[i] &= ~BUFFER_DIRTY; + bufferState[i] &= ~BUFFER_LOCKED; + } + + if (!sd.card()->writeStop()) + error("SD writeStop fail"); + + writeDisplayTimer = 25; + millitimerOff(); + + uint32_t writeTime = millis() - t0; + + snprintf(textBuf, TEXTBUF_SIZE, "Saved trk %02d in %lu ", trackNumber, writeTime); + LcdGoto(0,5); + LcdTinyString(textBuf, TEXT_NORMAL); + } + } +} + +int main(void) +{ + millitimerInit(); + ResetDiskState(); + + ShowVersion(); + + LcdClear(); + + sei(); + _delay_ms(100); // wait for pending interrupts?? + + millitimerOn(); + _delay_ms(100); // wait for pending interrupts?? + + // if select and next are both held down, enter contrast adjust mode + if (bit_is_set(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN) && + bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN) && + bit_is_clear(PIN(SELECT_BUTTON_PORT),SELECT_BUTTON_PIN)) + { + AdjustContrast(); + } + + SdFat sd; + if (!sd.init(SPI_FULL_SPEED)) + { + snprintf(textBuf, TEXTBUF_SIZE, "SD card error %d:%d", sd.card()->errorCode(), sd.card()->errorData()); + error(textBuf); + } + + millitimerOff(); + + // if prev and next are both held down, enter firmware update mode + if (bit_is_clear(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN) && + bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN) && + bit_is_set(PIN(SELECT_BUTTON_PORT),SELECT_BUTTON_PIN)) + { + PromptForFirmwareUpdate(); + } + + InitDiskMenu(sd); + DrawDiskMenu(sd); + + // main loop + while (true) + { + if (writeError) + { + // report error encounted in the interrupt routine + error(textBuf); + } + + cli(); + uint8_t trackNumber = currentTrack; // save track in a local var, since currentTrack is volatile + uint8_t sideNumber = currentSide; // save side in a local var, since currentSide is volatile + restartDisk = false; + sei(); + + if (diskInserted) + { + // show the current track and side + snprintf(textBuf, TEXTBUF_SIZE, "%02d", trackNumber); + LcdGoto(24,4); + LcdTinyString(textBuf, TEXT_NORMAL); + snprintf(textBuf, TEXTBUF_SIZE, "%d ", sideNumber); + LcdGoto(56,4); + LcdTinyString(textBuf, TEXT_NORMAL); + + // sync RAM buffer with SD card when switching tracks, or also when switching sides for mfmMode + if (prevTrack != trackNumber || (mfmMode && (prevSide != sideNumber))) + { + // write any dirty sectors from the previous track/side back to the SD card + FlushDirtySectors(sd, prevTrack); + prevTrack = trackNumber; + prevSide = sideNumber; + + // Also mark all the buffers on this track as invalid, since they don't contain valid data for the new track. + for (uint8_t i=0; i= trackLen) + currentSector = 0; + + bool prevMotorOn = !bit_is_clear(PIN(CPLD_STEP_DIR_MOTOR_ON_PORT), CPLD_STEP_DIR_MOTOR_ON_PIN); + + while (true) + { + // check for disk eject + if (bit_is_set(PIN(CPLD_EJECT_REQ_PORT), CPLD_EJECT_REQ_PIN)) + { + PORT(CPLD_RD_READY_TK0_PORT) &= ~(1<readBlock(blockToRead, sectorBuf[bufferNumber])) + error("SD read error R"); + } + + millitimerOff(); + + bufferState[bufferNumber] |= BUFFER_DATA_VALID; + bufferState[bufferNumber] &= ~BUFFER_LOCKED; + } + + if (currentSector == 0) + { + if (motorOn) + { + // toggle LED during drive activity + PORT(STATUS_LED_PORT) ^= (1< 1) + writeDisplayTimer--; + } + + // "Flutter" the drive's TACH speed slightly, every time we pass sector 0 (about every 100-150ms). This avoids a bug + // in P_Sony_MakeSpdTbl in the 64K ROM (used in the Mac 128K and Mac 512K) where + // the Mac will crash if two successive TACH measurements see the exact same speed. + tachFlutter += 25; + if (tachFlutter >= 125) + tachFlutter = 0; + + // Set the timeout. OC1A will toggle after this many counts. New timeout threshold won't take effect until the next timeout. + OCR1A = driveTachHalfPeriod - tachFlutter; + } + + if (mfmMode) + { + // insert sector-to-sector gap bytes + for (uint8_t i=0; i<50; i++) + { + SendMFMAndCheckRestart(0x4E); + } + + // insert sync bytes + for (uint8_t i=0; i<12; i++) + { + SendMFMAndCheckRestart(0x00); + } + + // send the address block + crc = 0xFFFF; // reset CRC + SendMFMSync(); + SendMFMSync(); + SendMFMSync(); + SendMFMAndCheckRestart(0xFE); + SendMFMAndCheckRestart(trackNumber); + SendMFMAndCheckRestart(sideNumber); + SendMFMAndCheckRestart(currentSector+1); // MFM sector numbers are 1-based + SendMFMAndCheckRestart(2); // size = 128 * 2^N bytes, so 2 means 512 + uint8_t crc0 = (crc >> 8) & 0xFF; + uint8_t crc1 = crc & 0xFF; + SendMFMAndCheckRestart(crc0); + SendMFMAndCheckRestart(crc1); + + // insert Address to Data gap bytes + for (uint8_t i=0; i<22; i++) + { + SendMFMAndCheckRestart(0x4E); + } + + // insert sync bytes + for (uint8_t i=0; i<12; i++) + { + SendMFMAndCheckRestart(0x00); + } + + // send the data block + crc = 0xFFFF; // reset CRC + SendMFMSync(); + SendMFMSync(); + SendMFMSync(); + SendMFMAndCheckRestart(0xFB); + + for (uint16_t i=0; i> 8) & 0xFF; + crc1 = crc & 0xFF; + SendMFMAndCheckRestart(crc0); + SendMFMAndCheckRestart(crc1); + } + else + { + // ensure a short gap between sectors - otherwise once they're all cached, one sector will appear + // to immediately follow another on disk, which may cause problems for the Mac. + // Bad voodoo here: + // 1. In the Finder StuffIt copy test that sometimes dies after the first 18 tracks, the length of delay here + // seems to affect what track it will freeze on. + // 2. With a longer delay here, the first ~10 sectors of copying seem to have fewer or no "long writes". + // 3. Depending on the delay here, the Transcend 2GB SD card sometimes gets "writeStop fail" when saving tracks. + for (uint16_t i=0; i> 6)); + uint8_t checksum = (uint8_t)((trackLow ^ currentSector ^ trackHigh ^ format) & 0x3F); + + SendByteAndCheckRestart(0xD5); + SendByteAndCheckRestart(0xAA); + SendByteAndCheckRestart(0x96); + SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[trackLow])); + SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[currentSector])); + SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[trackHigh])); + SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[format])); + SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[checksum])); + SendByteAndCheckRestart(0xDE); + SendByteAndCheckRestart(0xAA); + + // insert sync bytes between the address and data blocks + for (uint8_t i=0; i 0) + { + diskMenuSelection--; + DrawDiskMenu(sd); + _delay_ms(200); + } + } + else if (bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN)) + { + diskMenuSelection++; + DrawDiskMenu(sd); + _delay_ms(200); + } + else if (bit_is_clear(PIN(SELECT_BUTTON_PORT), SELECT_BUTTON_PIN)) + { + if (selectedFileType == DISK_IMAGE_DIRECTORY) + { + // remember where we came from, so we can get back later + char* pSubdirName = ((char*)sectorBuf[23]) + ((SHORTFILENAME_LEN+1) * subdirDepth); + strncpy(pSubdirName, selectedFile, SHORTFILENAME_LEN+1); + subdirDepth++; + + sd.chdir(selectedFile, true); + + diskMenuSelection = 0; + LcdClear(); + InitDiskMenu(sd); + DrawDiskMenu(sd); + _delay_ms(400); + } + else if (selectedFileType == DISK_IMAGE_UP_DIRECTORY) + { + subdirDepth--; + sd.chdir(true); // go to root directory + + for (uint8_t i=0; i + + + 2.0 + 5.1 + {e27520eb-9b21-411f-b8c6-71c8e4b8b1b6} + ATmega1284P + none + Executable + CPP + $(MSBuildProjectDirectory)\$(Configuration) + + + floppyemu + floppyemu + floppyemu + com.atmel.avrdbg.tool.ispmk2 + com.Atmel.AVRGCC8 + Native + 2.11.1 + ISP + + com.atmel.avrdbg.tool.ispmk2 + AVRISP mkII + 000200006259 + + 127.0.0.1 + 49229 + False + + + JTAG + + 1000000 + 1000000 + 150000 + false + false + 0 + 0 + 0 + 0 + + + + + + floppyemu + .elf + + + True + True + True + True + True + True + True + True + + + F_CPU=20000000 + + + + + ../SdFat + ../xsvf + + + Optimize more (-O2) + True + True + True + True + + + m + + + True + True + + + .bootldrinfo=0xF7FC + + + + + True + C:\Users\chamberlin\Documents\floppyemu\AVR\Release + C:\Users\chamberlin\Documents\floppyemu\AVR\Release\Makefile + + + floppyemu + .elf + + + True + True + True + True + True + True + True + True + True + Default (-g2) + True + + + m + + + Default (-g2) + + + + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + Sd2Card.cpp + + + compile + SdBaseFile.cpp + + + compile + SdFat.cpp + + + compile + SdVolume.cpp + + + compile + lenval.cpp + + + compile + lenval.h + + + compile + micro.cpp + + + compile + micro.h + + + compile + ports.cpp + + + compile + ports.h + + + + \ No newline at end of file diff --git a/source-1.0L-F11/AVR/millitimer.cpp b/source-1.0L-F11/AVR/millitimer.cpp new file mode 100755 index 0000000..c654447 --- /dev/null +++ b/source-1.0L-F11/AVR/millitimer.cpp @@ -0,0 +1,57 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#include +#include +#include "millitimer.h" + +static uint32_t milliCount; + +void millitimerInit() +{ + TCCR0A = 0; // normal counter mode + TCCR0B = (1< + +void millitimerInit(); +void millitimerOn(); +void millitimerOff(); +uint32_t millis(); + +#endif /* MILLITIMER_H_ */ \ No newline at end of file diff --git a/source-1.0L-F11/AVR/noklcd.cpp b/source-1.0L-F11/AVR/noklcd.cpp new file mode 100755 index 0000000..1bb86e8 --- /dev/null +++ b/source-1.0L-F11/AVR/noklcd.cpp @@ -0,0 +1,350 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. +*/ + +#include +#include +#include +#include +#include +#include + +#include "noklcd.h" +#include "portmacros.h" + +#define LCD_RESET_PORT B +#define LCD_RESET_PIN 0 + +#define LCD_CS_PORT B +#define LCD_CS_PIN 2 + +#define SPI_CLK_PORT B +#define SPI_CLK_PIN 7 + +#define SPI_DATA_PORT B +#define SPI_DATA_PIN 5 + +#define SPI_DC_PORT D +#define SPI_DC_PIN 6 + +volatile uint8_t lcd_vop; +volatile uint8_t lcd_bias; +volatile uint8_t lcd_tempCoef; + +extern const uint8_t tiny_font[][3] PROGMEM; +const uint8_t tiny_font[][3] = { + + {0x00,0x00,0x00}, // 20 + {0x00,0x17,0x00}, // 21 ! + {0x03,0x00,0x03}, // 22 " + {0x1f,0x0a,0x1f}, // 23 # + {0x0a,0x1f,0x05}, // 24 $ + {0x09,0x04,0x12}, // 25 % + {0x0f,0x17,0x1c}, // 26 & + {0x00,0x03,0x03}, // 27 ' -> degree + {0x00,0x0e,0x11}, // 28 ( + {0x11,0x0e,0x00}, // 29 ) + {0x05,0x02,0x05}, // 2a * + {0x04,0x0e,0x04}, // 2b + + {0x10,0x08,0x00}, // 2c , + {0x04,0x04,0x04}, // 2d - + {0x00,0x10,0x00}, // 2e . + {0x18,0x04,0x03}, // 2f / + {0x1e,0x11,0x0f}, // 30 0 + {0x02,0x1f,0x00}, // 31 1 + {0x19,0x15,0x12}, // 32 2 + {0x15,0x15,0x0a}, // 33 3 + {0x07,0x04,0x1f}, // 34 4 + {0x17,0x15,0x09}, // 35 5 + {0x1e,0x15,0x1d}, // 36 6 + {0x19,0x05,0x03}, // 37 7 + {0x1a,0x15,0x0b}, // 38 8 + {0x17,0x15,0x0f}, // 39 9 + {0x00,0x0a,0x00}, // 3a : + {0x04,0x0c,0x04}, // 3b ; -> down arrow + {0x04,0x0e,0x1f}, // 3c < + {0x0a,0x0a,0x0a}, // 3d = + {0x1f,0x0e,0x04}, // 3e > + {0x01,0x15,0x03}, // 3f ? + {0x0e,0x15,0x16}, // 40 @ + {0x1e,0x05,0x1e}, // 41 A + {0x1f,0x15,0x0a}, // 42 B + {0x0e,0x11,0x11}, // 43 C + {0x1f,0x11,0x0e}, // 44 D + {0x1f,0x15,0x15}, // 45 E + {0x1f,0x05,0x05}, // 46 F + {0x0e,0x15,0x1d}, // 47 G + {0x1f,0x04,0x1f}, // 48 H + {0x11,0x1f,0x11}, // 49 I + {0x08,0x10,0x0f}, // 4a J + {0x1f,0x04,0x1b}, // 4b K + {0x1f,0x10,0x10}, // 4c L + {0x1f,0x06,0x1f}, // 4d M + {0x1f,0x0e,0x1f}, // 4e N + {0x0e,0x11,0x0e}, // 4f O + {0x1f,0x05,0x02}, // 50 P + {0x0e,0x19,0x1e}, // 51 Q + {0x1f,0x0d,0x16}, // 52 R + {0x12,0x15,0x09}, // 53 S + {0x01,0x1f,0x01}, // 54 T + {0x0f,0x10,0x1f}, // 55 U + {0x07,0x18,0x07}, // 56 V + {0x1f,0x0c,0x1f}, // 57 W + {0x1b,0x04,0x1b}, // 58 X + {0x03,0x1c,0x03}, // 59 Y + {0x19,0x15,0x13}, // 5a Z + {0x1f,0x10,0x10}, // 5b [ + {0x02,0x04,0x08}, // 5c backslash + {0x10,0x10,0x1f}, // 5d ] + {0x04,0x06,0x04}, // 5e ^ + {0x10,0x10,0x10}, // 5f _ + {0x00,0x03,0x03}, // 60 ` -> degree + {0x1a,0x16,0x1c}, // 61 a + {0x1f,0x12,0x0c}, // 62 b + {0x0c,0x12,0x12}, // 63 c + {0x0c,0x12,0x1f}, // 64 d + {0x0c,0x1a,0x16}, // 65 e + {0x04,0x1e,0x05}, // 66 f + {0x0c,0x2a,0x1e}, // 67 g + {0x1f,0x02,0x1c}, // 68 h + {0x00,0x1d,0x00}, // 69 i + {0x10,0x20,0x1d}, // 6a j + {0x1f,0x0c,0x12}, // 6b k + {0x11,0x1f,0x10}, // 6c l + {0x1e,0x0e,0x1e}, // 6d m + {0x1e,0x02,0x1c}, // 6e n + {0x0c,0x12,0x0c}, // 6f o + {0x3e,0x12,0x0c}, // 70 p + {0x0c,0x12,0x3e}, // 71 q + {0x1c,0x02,0x02}, // 72 r + {0x14,0x1e,0x0a}, // 73 s + {0x02,0x1f,0x12}, // 74 t + {0x0e,0x10,0x1e}, // 75 u + {0x0e,0x18,0x0e}, // 76 v + {0x1e,0x1c,0x1e}, // 77 w + {0x12,0x0c,0x12}, // 78 x + {0x06,0x28,0x1e}, // 79 y + {0x1a,0x1f,0x16}, // 7a z + {0x04,0x1b,0x11}, // 7b { + {0x00,0x1f,0x00}, // 7c | + {0x11,0x1b,0x04}, // 7d } + {0x08,0x0c,0x04}, // 7e ~ +}; + +void LcdWrite(uint8_t dc, uint8_t data) +{ + // set SPI speed to "half speed": clock speed / 4 + SPCR = (1 << SPE) | (1 << MSTR); + SPSR = 0; + + if (dc) + { + PORT(SPI_DC_PORT) |= (1<> 1) | 0x40); + LcdWrite(LCD_DATA, (0x04 >> 1) | 0x40); + LcdWrite(LCD_DATA, (0x18 >> 1) | 0x40); + LcdWrite(LCD_DATA, (0x04 >> 1) | 0x40); + LcdWrite(LCD_DATA, (0x38 >> 1) | 0x40); + LcdWrite(LCD_DATA, (0x00 >> 1) | 0x40); + } + else + { + unsigned short charbase = (*characters++ - 0x20) * 3; + + for (uint8_t index = 0; index < 3; index++) + { + uint8_t pixels = pgm_read_byte((unsigned char*)tiny_font + charbase + index); + //pixels = pixels << 2; + pixels |= 0x40; + LcdWrite(LCD_DATA, pixels); + } + + LcdWrite(LCD_DATA, 0x40); + } + } +} + +void LcdClear(void) +{ + for (int index = 0; index < LCD_WIDTH * LCD_HEIGHT / 8; index++) + { + LcdWrite(LCD_DATA, 0x00); + } +} + +void LcdReset(void) +{ + lcd_vop = 0xBF; + lcd_bias = 0x14; + lcd_tempCoef = 0x04; + + // set pin directions + DDR(SPI_DC_PORT) |= (1< + +#define LCD_WIDTH 84 +#define LCD_HEIGHT 48 + +#define LCD_CMD 0 +#define LCD_DATA 1 + +#define TEXT_NORMAL 0 +#define TEXT_INVERSE 1 + +extern volatile uint8_t lcd_vop; +extern volatile uint8_t lcd_bias; +extern volatile uint8_t lcd_tempCoef; + +void LcdReset(void); +void LcdClear(void); +void LcdGoto(uint8_t x, uint8_t y); +void LcdWrite(uint8_t dc, uint8_t data); +void LcdTinyString(const char *characters, uint8_t inverse, uint8_t maxWidth = 84); +void LcdTinyStringP(PGM_P characters, uint8_t inverse); +void LcdTinyStringFramed(const char *characters); + +#endif /* NOKLCD_H_ */ diff --git a/source-1.0L-F11/AVR/portmacros.h b/source-1.0L-F11/AVR/portmacros.h new file mode 100755 index 0000000..3fb9a61 --- /dev/null +++ b/source-1.0L-F11/AVR/portmacros.h @@ -0,0 +1,20 @@ +/* + * portmacros.h + * + * Created: 11/16/2011 11:05:46 AM + * Author: steve + */ + + +#ifndef PORTMACROS_H_ +#define PORTMACROS_H_ + +#define PORT_(port) PORT ## port +#define DDR_(port) DDR ## port +#define PIN_(port) PIN ## port + +#define PORT(port) PORT_(port) +#define DDR(port) DDR_(port) +#define PIN(port) PIN_(port) + +#endif /* PORTMACROS_H_ */ \ No newline at end of file diff --git a/source-1.0L-F11/AVR/xsvf/lenval.cpp b/source-1.0L-F11/AVR/xsvf/lenval.cpp new file mode 100755 index 0000000..c96cae9 --- /dev/null +++ b/source-1.0L-F11/AVR/xsvf/lenval.cpp @@ -0,0 +1,190 @@ +/*******************************************************/ +/* file: lenval.c */ +/* abstract: This file contains routines for using */ +/* the lenVal data structure. */ +/*******************************************************/ +#include "lenval.h" +#include "ports.h" + +/***************************************************************************** +* Function: value +* Description: Extract the long value from the lenval array. +* Parameters: plvValue - ptr to lenval. +* Returns: long - the extracted value. +*****************************************************************************/ +long value( lenVal* plvValue ) +{ + long lValue; /* result to hold the accumulated result */ + short sIndex; + + lValue = 0; + for ( sIndex = 0; sIndex < plvValue->len ; ++sIndex ) + { + lValue <<= 8; /* shift the accumulated result */ + lValue |= plvValue->val[ sIndex]; /* get the last byte first */ + } + + return( lValue ); +} + +/***************************************************************************** +* Function: initLenVal +* Description: Initialize the lenval array with the given value. +* Assumes lValue is less than 256. +* Parameters: plv - ptr to lenval. +* lValue - the value to set. +* Returns: void. +*****************************************************************************/ +void initLenVal( lenVal* plv, + long lValue ) +{ + plv->len = 1; + plv->val[0] = (unsigned char)lValue; +} + +/***************************************************************************** +* Function: EqualLenVal +* Description: Compare two lenval arrays with an optional mask. +* Parameters: plvTdoExpected - ptr to lenval #1. +* plvTdoCaptured - ptr to lenval #2. +* plvTdoMask - optional ptr to mask (=0 if no mask). +* Returns: short - 0 = mismatch; 1 = equal. +*****************************************************************************/ +short EqualLenVal( lenVal* plvTdoExpected, + lenVal* plvTdoCaptured, + lenVal* plvTdoMask ) +{ + short sEqual; + short sIndex; + unsigned char ucByteVal1; + unsigned char ucByteVal2; + unsigned char ucByteMask; + + sEqual = 1; + sIndex = plvTdoExpected->len; + + while ( sEqual && sIndex-- ) + { + ucByteVal1 = plvTdoExpected->val[ sIndex ]; + ucByteVal2 = plvTdoCaptured->val[ sIndex ]; + if ( plvTdoMask ) + { + ucByteMask = plvTdoMask->val[ sIndex ]; + ucByteVal1 &= ucByteMask; + ucByteVal2 &= ucByteMask; + } + if ( ucByteVal1 != ucByteVal2 ) + { + sEqual = 0; + } + } + + return( sEqual ); +} + + +/***************************************************************************** +* Function: RetBit +* Description: return the (byte, bit) of lv (reading from left to right). +* Parameters: plv - ptr to lenval. +* iByte - the byte to get the bit from. +* iBit - the bit number (0=msb) +* Returns: short - the bit value. +*****************************************************************************/ +short RetBit( lenVal* plv, + int iByte, + int iBit ) +{ + /* assert( ( iByte >= 0 ) && ( iByte < plv->len ) ); */ + /* assert( ( iBit >= 0 ) && ( iBit < 8 ) ); */ + return( (short)( ( plv->val[ iByte ] >> ( 7 - iBit ) ) & 0x1 ) ); +} + +/***************************************************************************** +* Function: SetBit +* Description: set the (byte, bit) of lv equal to val +* Example: SetBit("00000000",byte, 1) equals "01000000". +* Parameters: plv - ptr to lenval. +* iByte - the byte to get the bit from. +* iBit - the bit number (0=msb). +* sVal - the bit value to set. +* Returns: void. +*****************************************************************************/ +void SetBit( lenVal* plv, + int iByte, + int iBit, + short sVal ) +{ + unsigned char ucByteVal; + unsigned char ucBitMask; + + ucBitMask = (unsigned char)(1 << ( 7 - iBit )); + ucByteVal = (unsigned char)(plv->val[ iByte ] & (~ucBitMask)); + + if ( sVal ) + { + ucByteVal |= ucBitMask; + } + plv->val[ iByte ] = ucByteVal; +} + +/***************************************************************************** +* Function: AddVal +* Description: add val1 to val2 and store in resVal; +* assumes val1 and val2 are of equal length. +* Parameters: plvResVal - ptr to result. +* plvVal1 - ptr of addendum. +* plvVal2 - ptr of addendum. +* Returns: void. +*****************************************************************************/ +void addVal( lenVal* plvResVal, + lenVal* plvVal1, + lenVal* plvVal2 ) +{ + unsigned char ucCarry; + unsigned short usSum; + unsigned short usVal1; + unsigned short usVal2; + short sIndex; + + plvResVal->len = plvVal1->len; /* set up length of result */ + + /* start at least significant bit and add bytes */ + ucCarry = 0; + sIndex = plvVal1->len; + while ( sIndex-- ) + { + usVal1 = plvVal1->val[ sIndex ]; /* i'th byte of val1 */ + usVal2 = plvVal2->val[ sIndex ]; /* i'th byte of val2 */ + + /* add the two bytes plus carry from previous addition */ + usSum = (unsigned short)( usVal1 + usVal2 + ucCarry ); + + /* set up carry for next byte */ + ucCarry = (unsigned char)( ( usSum > 255 ) ? 1 : 0 ); + + /* set the i'th byte of the result */ + plvResVal->val[ sIndex ] = (unsigned char)usSum; + } +} + +/***************************************************************************** +* Function: readVal +* Description: read from XSVF numBytes bytes of data into x. +* Parameters: plv - ptr to lenval in which to put the bytes read. +* sNumBytes - the number of bytes to read. +* Returns: void. +*****************************************************************************/ +void readVal( lenVal* plv, + short sNumBytes ) +{ + unsigned char* pucVal; + + plv->len = sNumBytes; /* set the length of the lenVal */ + for ( pucVal = plv->val; sNumBytes; --sNumBytes, ++pucVal ) + { + /* read a byte of data into the lenVal */ + readByte( pucVal ); + } +} + diff --git a/source-1.0L-F11/AVR/xsvf/lenval.h b/source-1.0L-F11/AVR/xsvf/lenval.h new file mode 100755 index 0000000..2838508 --- /dev/null +++ b/source-1.0L-F11/AVR/xsvf/lenval.h @@ -0,0 +1,93 @@ +/*******************************************************/ +/* file: lenval.h */ +/* abstract: This file contains a description of the */ +/* data structure "lenval". */ +/*******************************************************/ + +#ifndef lenval_dot_h +#define lenval_dot_h + +/* the lenVal structure is a byte oriented type used to store an */ +/* arbitrary length binary value. As an example, the hex value */ +/* 0x0e3d is represented as a lenVal with len=2 (since 2 bytes */ +/* and val[0]=0e and val[1]=3d. val[2-MAX_LEN] are undefined */ + +/* maximum length (in bytes) of value to read in */ +/* this needs to be at least 4, and longer than the */ +/* length of the longest SDR instruction. If there is, */ +/* only 1 device in the chain, MAX_LEN must be at least */ +/* ceil(27/8) == 4. For 6 devices in a chain, MAX_LEN */ +/* must be 5, for 14 devices MAX_LEN must be 6, for 20 */ +/* devices MAX_LEN must be 7, etc.. */ +/* You can safely set MAX_LEN to a smaller number if you*/ +/* know how many devices will be in your chain. */ +/* #define MAX_LEN (Actual #define is below this comment block) + This #define defines the maximum length (in bytes) of predefined + buffers in which the XSVF player stores the current shift data. + This length must be greater than the longest shift length (in bytes) + in the XSVF files that will be processed. 7000 is a very conservative + number. The buffers are stored on the stack and if you have limited + stack space, you may decrease the MAX_LEN value. + + How to find the "shift length" in bits? + Look at the ASCII version of the XSVF (generated with the -a option + for the SVF2XSVF translator) and search for the XSDRSIZE command + with the biggest parameter. XSDRSIZE is equivalent to the SVF's + SDR length plus the lengths of applicable HDR and TDR commands. + Remember that the MAX_LEN is defined in bytes. Therefore, the + minimum MAX_LEN = ceil( max( XSDRSIZE ) / 8 ); + + The following MAX_LEN values have been tested and provide relatively + good margin for the corresponding devices: + + DEVICE MAX_LEN Resulting Shift Length Max (in bits) + --------- ------- ---------------------------------------------- + XC9500/XL/XV 32 256 + + CoolRunner/II 256 2048 - actual max 1 device = 1035 bits + + FPGA 128 1024 - svf2xsvf -rlen 1024 + + XC18V00/XCF00 + 1100 8800 - no blank check performed (default) + - actual max 1 device = 8192 bits verify + - max 1 device = 4096 bits program-only + + XC18V00/XCF00 when using the optional Blank Check operation + 2500 20000 - required for blank check + - blank check max 1 device = 16384 bits +*/ +#define MAX_LEN 32 + + +typedef struct var_len_byte +{ + short len; /* number of chars in this value */ + unsigned char val[MAX_LEN+1]; /* bytes of data */ +} lenVal; + + +/* return the long representation of a lenVal */ +extern long value(lenVal *x); + +/* set lenVal equal to value */ +extern void initLenVal(lenVal *x, long value); + +/* check if expected equals actual (taking the mask into account) */ +extern short EqualLenVal(lenVal *expected, lenVal *actual, lenVal *mask); + +/* add val1+val2 and put the result in resVal */ +extern void addVal(lenVal *resVal, lenVal *val1, lenVal *val2); + +/* return the (byte, bit) of lv (reading from left to right) */ +extern short RetBit(lenVal *lv, int byte, int bit); + +/* set the (byte, bit) of lv equal to val (e.g. SetBit("00000000",byte, 1) + equals "01000000" */ +extern void SetBit(lenVal *lv, int byte, int bit, short val); + +/* read from XSVF numBytes bytes of data into x */ +extern void readVal(lenVal *x, short numBytes); + +#endif + diff --git a/source-1.0L-F11/AVR/xsvf/micro.cpp b/source-1.0L-F11/AVR/xsvf/micro.cpp new file mode 100755 index 0000000..4b09865 --- /dev/null +++ b/source-1.0L-F11/AVR/xsvf/micro.cpp @@ -0,0 +1,1820 @@ +/***************************************************************************** +* file: micro.c +* abstract: This file contains the function, xsvfExecute(), +* call for interpreting the XSVF commands. +* Usage: Call xsvfExecute() to process XSVF data. +* The XSVF data is retrieved by readByte() in ports.c +* Remove the main function if you already have one. +* Options: XSVF_SUPPORT_COMPRESSION +* This define supports the XC9500/XL compression scheme. +* This define adds support for XSDRINC and XSETSDRMASKS. +* XSVF_SUPPORT_ERRORCODES +* This define causes the xsvfExecute function to return +* an error code for specific errors. See error codes below. +* If this is not defined, the return value defaults to the +* legacy values for backward compatibility: +* 1 = success; 0 = failure. +* Debugging: DEBUG_MODE (Legacy name) +* Define DEBUG_MODE to compile with debugging features. +* Both micro.c and ports.c must be compiled with the DEBUG_MODE +* defined to enable the standalone main implementation in +* micro.c that reads XSVF from a file. +* History: v2.00 - Original XSVF implementation. +* v4.04 - Added delay at end of XSIR for XC18v00 support. +* Added new commands for CoolRunner support: +* XSTATE, XENDIR, XENDDR +* v4.05 - Cleanup micro.c but leave ports.c intact. +* v4.06 - Fix xsvfGotoTapState for retry transition. +* v4.07 - Update example waitTime implementations for +* compatibility with Virtex-II. +* v4.10 - Add new XSIR2 command that supports a 2-byte +* IR-length parameter for IR shifts > 255 bits. +* v4.11 - No change. Update version to match SVF2XSVF xlator. +* v4.14 - Added XCOMMENT. +* v5.00 - Improve XSTATE support. +* Added XWAIT. +* v5.01 - make sure that TCK is low during RUNTEST wait for +* XC18V00/XCF00 support. Only change is in PORTS.C +* waitTime() function for implementations that do NOT +* pulse TCK during the waitTime. +*****************************************************************************/ + + + +/*============================================================================ +* #include files +============================================================================*/ +//#define DEBUG_MODE + +#include "micro.h" +#include "lenval.h" +#include "ports.h" + + +/*============================================================================ +* XSVF #define +============================================================================*/ + +#define XSVF_VERSION "5.01" + +/***************************************************************************** +* Define: XSVF_SUPPORT_COMPRESSION +* Description: Define this to support the XC9500/XL XSVF data compression +* scheme. +* Code size can be reduced by NOT supporting this feature. +* However, you must use the -nc (no compress) option when +* translating SVF to XSVF using the SVF2XSVF translator. +* Corresponding, uncompressed XSVF may be larger. +*****************************************************************************/ +#ifndef XSVF_SUPPORT_COMPRESSION + #define XSVF_SUPPORT_COMPRESSION 1 +#endif + +/***************************************************************************** +* Define: XSVF_SUPPORT_ERRORCODES +* Description: Define this to support the new XSVF error codes. +* (The original XSVF player just returned 1 for success and +* 0 for an unspecified failure.) +*****************************************************************************/ +#ifndef XSVF_SUPPORT_ERRORCODES + #define XSVF_SUPPORT_ERRORCODES 1 +#endif + +#ifdef XSVF_SUPPORT_ERRORCODES + #define XSVF_ERRORCODE(errorCode) errorCode +#else /* Use legacy error code */ + #define XSVF_ERRORCODE(errorCode) ((errorCode==XSVF_ERROR_NONE)?1:0) +#endif /* XSVF_SUPPORT_ERRORCODES */ + + +/***************************************************************************** +* Define: XSVF_MAIN +* Description: Define this to compile with a main function for standalone +* debugging. +*****************************************************************************/ +#ifndef XSVF_MAIN + #ifdef DEBUG_MODE + #define XSVF_MAIN 1 + #endif /* DEBUG_MODE */ +#endif /* XSVF_MAIN */ + + +/*============================================================================ +* DEBUG_MODE #define +============================================================================*/ + +#ifdef DEBUG_MODE + #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat ); } + #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat, arg1 ); } + #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat, arg1, arg2 ); } + #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat, arg1, arg2, arg3 ); } + #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + xsvfPrintLenVal(plenVal); } +#else /* !DEBUG_MODE */ + #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) + #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) + #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) + #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) + #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) +#endif /* DEBUG_MODE */ + + +/*============================================================================ +* XSVF Type Declarations +============================================================================*/ + +/***************************************************************************** +* Struct: SXsvfInfo +* Description: This structure contains all of the data used during the +* execution of the XSVF. Some data is persistent, predefined +* information (e.g. lRunTestTime). The bulk of this struct's +* size is due to the lenVal structs (defined in lenval.h) +* which contain buffers for the active shift data. The MAX_LEN +* #define in lenval.h defines the size of these buffers. +* These buffers must be large enough to store the longest +* shift data in your XSVF file. For example: +* MAX_LEN >= ( longest_shift_data_in_bits / 8 ) +* Because the lenVal struct dominates the space usage of this +* struct, the rough size of this struct is: +* sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals) +* xsvfInitialize() contains initialization code for the data +* in this struct. +* xsvfCleanup() contains cleanup code for the data in this +* struct. +*****************************************************************************/ +typedef struct tagSXsvfInfo +{ + /* XSVF status information */ + unsigned char ucComplete; /* 0 = running; 1 = complete */ + unsigned char ucCommand; /* Current XSVF command byte */ + long lCommandCount; /* Number of commands processed */ + int iErrorCode; /* An error code. 0 = no error. */ + + /* TAP state/sequencing information */ + unsigned char ucTapState; /* Current TAP state */ + unsigned char ucEndIR; /* ENDIR TAP state (See SVF) */ + unsigned char ucEndDR; /* ENDDR TAP state (See SVF) */ + + /* RUNTEST information */ + unsigned char ucMaxRepeat; /* Max repeat loops (for xc9500/xl) */ + long lRunTestTime; /* Pre-specified RUNTEST time (usec) */ + + /* Shift Data Info and Buffers */ + long lShiftLengthBits; /* Len. current shift data in bits */ + short sShiftLengthBytes; /* Len. current shift data in bytes */ + + lenVal lvTdi; /* Current TDI shift data */ + lenVal lvTdoExpected; /* Expected TDO shift data */ + lenVal lvTdoCaptured; /* Captured TDO shift data */ + lenVal lvTdoMask; /* TDO mask: 0=dontcare; 1=compare */ + +#ifdef XSVF_SUPPORT_COMPRESSION + /* XSDRINC Data Buffers */ + lenVal lvAddressMask; /* Address mask for XSDRINC */ + lenVal lvDataMask; /* Data mask for XSDRINC */ + lenVal lvNextData; /* Next data for XSDRINC */ +#endif /* XSVF_SUPPORT_COMPRESSION */ +} SXsvfInfo; + +/* Declare pointer to functions that perform XSVF commands */ +typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* ); + + +/*============================================================================ +* XSVF Command Bytes +============================================================================*/ + +/* encodings of xsvf instructions */ +#define XCOMPLETE 0 +#define XTDOMASK 1 +#define XSIR 2 +#define XSDR 3 +#define XRUNTEST 4 +/* Reserved 5 */ +/* Reserved 6 */ +#define XREPEAT 7 +#define XSDRSIZE 8 +#define XSDRTDO 9 +#define XSETSDRMASKS 10 +#define XSDRINC 11 +#define XSDRB 12 +#define XSDRC 13 +#define XSDRE 14 +#define XSDRTDOB 15 +#define XSDRTDOC 16 +#define XSDRTDOE 17 +#define XSTATE 18 /* 4.00 */ +#define XENDIR 19 /* 4.04 */ +#define XENDDR 20 /* 4.04 */ +#define XSIR2 21 /* 4.10 */ +#define XCOMMENT 22 /* 4.14 */ +#define XWAIT 23 /* 5.00 */ +/* Insert new commands here */ +/* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */ +#define XLASTCMD 24 /* Last command marker */ + + +/*============================================================================ +* XSVF Command Parameter Values +============================================================================*/ + +#define XSTATE_RESET 0 /* 4.00 parameter for XSTATE */ +#define XSTATE_RUNTEST 1 /* 4.00 parameter for XSTATE */ + +#define XENDXR_RUNTEST 0 /* 4.04 parameter for XENDIR/DR */ +#define XENDXR_PAUSE 1 /* 4.04 parameter for XENDIR/DR */ + +/* TAP states */ +#define XTAPSTATE_RESET 0x00 +#define XTAPSTATE_RUNTEST 0x01 /* a.k.a. IDLE */ +#define XTAPSTATE_SELECTDR 0x02 +#define XTAPSTATE_CAPTUREDR 0x03 +#define XTAPSTATE_SHIFTDR 0x04 +#define XTAPSTATE_EXIT1DR 0x05 +#define XTAPSTATE_PAUSEDR 0x06 +#define XTAPSTATE_EXIT2DR 0x07 +#define XTAPSTATE_UPDATEDR 0x08 +#define XTAPSTATE_IRSTATES 0x09 /* All IR states begin here */ +#define XTAPSTATE_SELECTIR 0x09 +#define XTAPSTATE_CAPTUREIR 0x0A +#define XTAPSTATE_SHIFTIR 0x0B +#define XTAPSTATE_EXIT1IR 0x0C +#define XTAPSTATE_PAUSEIR 0x0D +#define XTAPSTATE_EXIT2IR 0x0E +#define XTAPSTATE_UPDATEIR 0x0F + +/*============================================================================ +* XSVF Function Prototypes +============================================================================*/ + +int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ); /* Illegal command function */ +int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSIR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo ); +int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo ); +int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo ); +/* Insert new command functions here */ + +/*============================================================================ +* XSVF Global Variables +============================================================================*/ + +/* Array of XSVF command functions. Must follow command byte value order! */ +/* If your compiler cannot take this form, then convert to a switch statement*/ +TXsvfDoCmdFuncPtr xsvf_pfDoCmd[] = +{ + xsvfDoXCOMPLETE, /* 0 */ + xsvfDoXTDOMASK, /* 1 */ + xsvfDoXSIR, /* 2 */ + xsvfDoXSDR, /* 3 */ + xsvfDoXRUNTEST, /* 4 */ + xsvfDoIllegalCmd, /* 5 */ + xsvfDoIllegalCmd, /* 6 */ + xsvfDoXREPEAT, /* 7 */ + xsvfDoXSDRSIZE, /* 8 */ + xsvfDoXSDRTDO, /* 9 */ +#ifdef XSVF_SUPPORT_COMPRESSION + xsvfDoXSETSDRMASKS, /* 10 */ + xsvfDoXSDRINC, /* 11 */ +#else + xsvfDoIllegalCmd, /* 10 */ + xsvfDoIllegalCmd, /* 11 */ +#endif /* XSVF_SUPPORT_COMPRESSION */ + xsvfDoXSDRBCE, /* 12 */ + xsvfDoXSDRBCE, /* 13 */ + xsvfDoXSDRBCE, /* 14 */ + xsvfDoXSDRTDOBCE, /* 15 */ + xsvfDoXSDRTDOBCE, /* 16 */ + xsvfDoXSDRTDOBCE, /* 17 */ + xsvfDoXSTATE, /* 18 */ + xsvfDoXENDXR, /* 19 */ + xsvfDoXENDXR, /* 20 */ + xsvfDoXSIR2, /* 21 */ + xsvfDoXCOMMENT, /* 22 */ + xsvfDoXWAIT /* 23 */ +/* Insert new command functions here */ +}; + +#ifdef DEBUG_MODE + char* xsvf_pzCommandName[] = + { + "XCOMPLETE", + "XTDOMASK", + "XSIR", + "XSDR", + "XRUNTEST", + "Reserved5", + "Reserved6", + "XREPEAT", + "XSDRSIZE", + "XSDRTDO", + "XSETSDRMASKS", + "XSDRINC", + "XSDRB", + "XSDRC", + "XSDRE", + "XSDRTDOB", + "XSDRTDOC", + "XSDRTDOE", + "XSTATE", + "XENDIR", + "XENDDR", + "XSIR2", + "XCOMMENT", + "XWAIT" + }; + + char* xsvf_pzErrorName[] = + { + "No error", + "ERROR: Unknown", + "ERROR: TDO mismatch", + "ERROR: TDO mismatch and exceeded max retries", + "ERROR: Unsupported XSVF command", + "ERROR: Illegal state specification", + "ERROR: Data overflows allocated MAX_LEN buffer size" + }; + + char* xsvf_pzTapState[] = + { + "RESET", /* 0x00 */ + "RUNTEST/IDLE", /* 0x01 */ + "DRSELECT", /* 0x02 */ + "DRCAPTURE", /* 0x03 */ + "DRSHIFT", /* 0x04 */ + "DREXIT1", /* 0x05 */ + "DRPAUSE", /* 0x06 */ + "DREXIT2", /* 0x07 */ + "DRUPDATE", /* 0x08 */ + "IRSELECT", /* 0x09 */ + "IRCAPTURE", /* 0x0A */ + "IRSHIFT", /* 0x0B */ + "IREXIT1", /* 0x0C */ + "IRPAUSE", /* 0x0D */ + "IREXIT2", /* 0x0E */ + "IRUPDATE" /* 0x0F */ + }; +#endif /* DEBUG_MODE */ + +#ifdef DEBUG_MODE + FILE* in; /* Legacy DEBUG_MODE file pointer */ + int xsvf_iDebugLevel; +#endif /* DEBUG_MODE */ + +/*============================================================================ +* Utility Functions +============================================================================*/ + +/***************************************************************************** +* Function: xsvfPrintLenVal +* Description: Print the lenval value in hex. +* Parameters: plv - ptr to lenval. +* Returns: void. +*****************************************************************************/ +#ifdef DEBUG_MODE +void xsvfPrintLenVal( lenVal *plv ) +{ + int i; + + if ( plv ) + { + printf( "0x" ); + for ( i = 0; i < plv->len; ++i ) + { + printf( "%02x", ((unsigned int)(plv->val[ i ])) ); + } + } +} +#endif /* DEBUG_MODE */ + + +/***************************************************************************** +* Function: xsvfInfoInit +* Description: Initialize the xsvfInfo data. +* Parameters: pXsvfInfo - ptr to the XSVF info structure. +* Returns: int - 0 = success; otherwise error. +*****************************************************************************/ +int xsvfInfoInit( SXsvfInfo* pXsvfInfo ) +{ + XSVFDBG_PRINTF1( 4, " sizeof( SXsvfInfo ) = %d bytes\n", + sizeof( SXsvfInfo ) ); + + pXsvfInfo->ucComplete = 0; + pXsvfInfo->ucCommand = XCOMPLETE; + pXsvfInfo->lCommandCount = 0; + pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; + pXsvfInfo->ucMaxRepeat = 0; + pXsvfInfo->ucTapState = XTAPSTATE_RESET; + pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST; + pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST; + pXsvfInfo->lShiftLengthBits = 0L; + pXsvfInfo->sShiftLengthBytes= 0; + pXsvfInfo->lRunTestTime = 0L; + + return( 0 ); +} + +/***************************************************************************** +* Function: xsvfInfoCleanup +* Description: Cleanup the xsvfInfo data. +* Parameters: pXsvfInfo - ptr to the XSVF info structure. +* Returns: void. +*****************************************************************************/ +void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo ) +{ +} + +/***************************************************************************** +* Function: xsvfGetAsNumBytes +* Description: Calculate the number of bytes the given number of bits +* consumes. +* Parameters: lNumBits - the number of bits. +* Returns: short - the number of bytes to store the number of bits. +*****************************************************************************/ +short xsvfGetAsNumBytes( long lNumBits ) +{ + return( (short)( ( lNumBits + 7L ) / 8L ) ); +} + +/***************************************************************************** +* Function: xsvfTmsTransition +* Description: Apply TMS and transition TAP controller by applying one TCK +* cycle. +* Parameters: sTms - new TMS value. +* Returns: void. +*****************************************************************************/ +void xsvfTmsTransition( short sTms ) +{ + setPort( TMS, sTms ); + setPort( TCK, 0 ); + setPort( TCK, 1 ); +} + +/***************************************************************************** +* Function: xsvfGotoTapState +* Description: From the current TAP state, go to the named TAP state. +* A target state of RESET ALWAYS causes TMS reset sequence. +* All SVF standard stable state paths are supported. +* All state transitions are supported except for the following +* which cause an XSVF_ERROR_ILLEGALSTATE: +* - Target==DREXIT2; Start!=DRPAUSE +* - Target==IREXIT2; Start!=IRPAUSE +* Parameters: pucTapState - Current TAP state; returns final TAP state. +* ucTargetState - New target TAP state. +* Returns: int - 0 = success; otherwise error. +*****************************************************************************/ +int xsvfGotoTapState( unsigned char* pucTapState, + unsigned char ucTargetState ) +{ + int i; + int iErrorCode; + + iErrorCode = XSVF_ERROR_NONE; + if ( ucTargetState == XTAPSTATE_RESET ) + { + /* If RESET, always perform TMS reset sequence to reset/sync TAPs */ + xsvfTmsTransition( 1 ); + for ( i = 0; i < 5; ++i ) + { + setPort( TCK, 0 ); + setPort( TCK, 1 ); + } + *pucTapState = XTAPSTATE_RESET; + XSVFDBG_PRINTF( 3, " TMS Reset Sequence -> Test-Logic-Reset\n" ); + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + else if ( ( ucTargetState != *pucTapState ) && + ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) || + ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) ) + { + /* Trap illegal TAP state path specification */ + iErrorCode = XSVF_ERROR_ILLEGALSTATE; + } + else + { + if ( ucTargetState == *pucTapState ) + { + /* Already in target state. Do nothing except when in DRPAUSE + or in IRPAUSE to comply with SVF standard */ + if ( ucTargetState == XTAPSTATE_PAUSEDR ) + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2DR; + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + else if ( ucTargetState == XTAPSTATE_PAUSEIR ) + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2IR; + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + } + + /* Perform TAP state transitions to get to the target state */ + while ( ucTargetState != *pucTapState ) + { + switch ( *pucTapState ) + { + case XTAPSTATE_RESET: + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_RUNTEST; + break; + case XTAPSTATE_RUNTEST: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTDR; + break; + case XTAPSTATE_SELECTDR: + if ( ucTargetState >= XTAPSTATE_IRSTATES ) + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTIR; + } + else + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_CAPTUREDR; + } + break; + case XTAPSTATE_CAPTUREDR: + if ( ucTargetState == XTAPSTATE_SHIFTDR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTDR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1DR; + } + break; + case XTAPSTATE_SHIFTDR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1DR; + break; + case XTAPSTATE_EXIT1DR: + if ( ucTargetState == XTAPSTATE_PAUSEDR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_PAUSEDR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEDR; + } + break; + case XTAPSTATE_PAUSEDR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2DR; + break; + case XTAPSTATE_EXIT2DR: + if ( ucTargetState == XTAPSTATE_SHIFTDR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTDR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEDR; + } + break; + case XTAPSTATE_UPDATEDR: + if ( ucTargetState == XTAPSTATE_RUNTEST ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_RUNTEST; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTDR; + } + break; + case XTAPSTATE_SELECTIR: + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_CAPTUREIR; + break; + case XTAPSTATE_CAPTUREIR: + if ( ucTargetState == XTAPSTATE_SHIFTIR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTIR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1IR; + } + break; + case XTAPSTATE_SHIFTIR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1IR; + break; + case XTAPSTATE_EXIT1IR: + if ( ucTargetState == XTAPSTATE_PAUSEIR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_PAUSEIR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEIR; + } + break; + case XTAPSTATE_PAUSEIR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2IR; + break; + case XTAPSTATE_EXIT2IR: + if ( ucTargetState == XTAPSTATE_SHIFTIR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTIR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEIR; + } + break; + case XTAPSTATE_UPDATEIR: + if ( ucTargetState == XTAPSTATE_RUNTEST ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_RUNTEST; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTDR; + } + break; + default: + iErrorCode = XSVF_ERROR_ILLEGALSTATE; + *pucTapState = ucTargetState; /* Exit while loop */ + break; + } + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + } + + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfShiftOnly +* Description: Assumes that starting TAP state is SHIFT-DR or SHIFT-IR. +* Shift the given TDI data into the JTAG scan chain. +* Optionally, save the TDO data shifted out of the scan chain. +* Last shift cycle is special: capture last TDO, set last TDI, +* but does not pulse TCK. Caller must pulse TCK and optionally +* set TMS=1 to exit shift state. +* Parameters: lNumBits - number of bits to shift. +* plvTdi - ptr to lenval for TDI data. +* plvTdoCaptured - ptr to lenval for storing captured TDO data. +* iExitShift - 1=exit at end of shift; 0=stay in Shift-DR. +* Returns: void. +*****************************************************************************/ +void xsvfShiftOnly( long lNumBits, + lenVal* plvTdi, + lenVal* plvTdoCaptured, + int iExitShift ) +{ + unsigned char* pucTdi; + unsigned char* pucTdo; + unsigned char ucTdiByte; + unsigned char ucTdoByte; + unsigned char ucTdoBit; + int i; + + /* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */ + + /* Initialize TDO storage len == TDI len */ + pucTdo = 0; + if ( plvTdoCaptured ) + { + plvTdoCaptured->len = plvTdi->len; + pucTdo = plvTdoCaptured->val + plvTdi->len; + } + + /* Shift LSB first. val[N-1] == LSB. val[0] == MSB. */ + pucTdi = plvTdi->val + plvTdi->len; + while ( lNumBits ) + { + /* Process on a byte-basis */ + ucTdiByte = (*(--pucTdi)); + ucTdoByte = 0; + for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i ) + { + --lNumBits; + if ( iExitShift && !lNumBits ) + { + /* Exit Shift-DR state */ + setPort( TMS, 1 ); + } + + /* Set the new TDI value */ + setPort( TDI, (short)(ucTdiByte & 1) ); + ucTdiByte >>= 1; + + /* Set TCK low */ + setPort( TCK, 0 ); + + if ( pucTdo ) + { + /* Save the TDO value */ + ucTdoBit = readTDOBit(); + ucTdoByte |= ( ucTdoBit << i ); + } + + /* Set TCK high */ + setPort( TCK, 1 ); + } + + /* Save the TDO byte value */ + if ( pucTdo ) + { + (*(--pucTdo)) = ucTdoByte; + } + } +} + +/***************************************************************************** +* Function: xsvfShift +* Description: Goes to the given starting TAP state. +* Calls xsvfShiftOnly to shift in the given TDI data and +* optionally capture the TDO data. +* Compares the TDO captured data against the TDO expected +* data. +* If a data mismatch occurs, then executes the exception +* handling loop upto ucMaxRepeat times. +* Parameters: pucTapState - Ptr to current TAP state. +* ucStartState - Starting shift state: Shift-DR or Shift-IR. +* lNumBits - number of bits to shift. +* plvTdi - ptr to lenval for TDI data. +* plvTdoCaptured - ptr to lenval for storing TDO data. +* plvTdoExpected - ptr to expected TDO data. +* plvTdoMask - ptr to TDO mask. +* ucEndState - state in which to end the shift. +* lRunTestTime - amount of time to wait after the shift. +* ucMaxRepeat - Maximum number of retries on TDO mismatch. +* Returns: int - 0 = success; otherwise TDO mismatch. +* Notes: XC9500XL-only Optimization: +* Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1] +* is NOT all zeros and sMatch==1. +*****************************************************************************/ +int xsvfShift( unsigned char* pucTapState, + unsigned char ucStartState, + long lNumBits, + lenVal* plvTdi, + lenVal* plvTdoCaptured, + lenVal* plvTdoExpected, + lenVal* plvTdoMask, + unsigned char ucEndState, + long lRunTestTime, + unsigned char ucMaxRepeat ) +{ + int iErrorCode; + int iMismatch; + unsigned char ucRepeat; + int iExitShift; + + iErrorCode = XSVF_ERROR_NONE; + iMismatch = 0; + ucRepeat = 0; + iExitShift = ( ucStartState != ucEndState ); + + XSVFDBG_PRINTF1( 3, " Shift Length = %ld\n", lNumBits ); + XSVFDBG_PRINTF( 4, " TDI = "); + XSVFDBG_PRINTLENVAL( 4, plvTdi ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF( 4, " TDO Expected = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoExpected ); + XSVFDBG_PRINTF( 4, "\n"); + + if ( !lNumBits ) + { + /* Compatibility with XSVF2.00: XSDR 0 = no shift, but wait in RTI */ + if ( lRunTestTime ) + { + /* Wait for prespecified XRUNTEST time */ + xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST ); + XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime ); + waitTime( lRunTestTime ); + } + } + else + { + do + { + /* Goto Shift-DR or Shift-IR */ + xsvfGotoTapState( pucTapState, ucStartState ); + + /* Shift TDI and capture TDO */ + xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift ); + + if ( plvTdoExpected ) + { + /* Compare TDO data to expected TDO data */ + iMismatch = !EqualLenVal( plvTdoExpected, + plvTdoCaptured, + plvTdoMask ); + } + + if ( iExitShift ) + { + /* Update TAP state: Shift->Exit */ + ++(*pucTapState); + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + + if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) ) + { + XSVFDBG_PRINTF( 4, " TDO Expected = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoExpected ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF( 4, " TDO Captured = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF( 4, " TDO Mask = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoMask ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF1( 3, " Retry #%d\n", ( ucRepeat + 1 ) ); + /* Do exception handling retry - ShiftDR only */ + xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR ); + /* Shift 1 extra bit */ + xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR ); + /* Increment RUNTEST time by an additional 25% */ + lRunTestTime += ( lRunTestTime >> 2 ); + } + else + { + /* Do normal exit from Shift-XR */ + xsvfGotoTapState( pucTapState, ucEndState ); + } + + if ( lRunTestTime ) + { + /* Wait for prespecified XRUNTEST time */ + xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST ); + XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime ); + waitTime( lRunTestTime ); + } + } + } while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) ); + } + + if ( iMismatch ) + { + XSVFDBG_PRINTF( 1, " TDO Expected = "); + XSVFDBG_PRINTLENVAL( 1, plvTdoExpected ); + XSVFDBG_PRINTF( 1, "\n"); + XSVFDBG_PRINTF( 1, " TDO Captured = "); + XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured ); + XSVFDBG_PRINTF( 1, "\n"); + XSVFDBG_PRINTF( 1, " TDO Mask = "); + XSVFDBG_PRINTLENVAL( 1, plvTdoMask ); + XSVFDBG_PRINTF( 1, "\n"); + if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) ) + { + iErrorCode = XSVF_ERROR_MAXRETRIES; + } + else + { + iErrorCode = XSVF_ERROR_TDOMISMATCH; + } + } + + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfBasicXSDRTDO +* Description: Get the XSDRTDO parameters and execute the XSDRTDO command. +* This is the common function for all XSDRTDO commands. +* Parameters: pucTapState - Current TAP state. +* lShiftLengthBits - number of bits to shift. +* sShiftLengthBytes - number of bytes to read. +* plvTdi - ptr to lenval for TDI data. +* lvTdoCaptured - ptr to lenval for storing TDO data. +* iEndState - state in which to end the shift. +* lRunTestTime - amount of time to wait after the shift. +* ucMaxRepeat - maximum xc9500/xl retries. +* Returns: int - 0 = success; otherwise TDO mismatch. +*****************************************************************************/ +int xsvfBasicXSDRTDO( unsigned char* pucTapState, + long lShiftLengthBits, + short sShiftLengthBytes, + lenVal* plvTdi, + lenVal* plvTdoCaptured, + lenVal* plvTdoExpected, + lenVal* plvTdoMask, + unsigned char ucEndState, + long lRunTestTime, + unsigned char ucMaxRepeat ) +{ + readVal( plvTdi, sShiftLengthBytes ); + if ( plvTdoExpected ) + { + readVal( plvTdoExpected, sShiftLengthBytes ); + } + return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits, + plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask, + ucEndState, lRunTestTime, ucMaxRepeat ) ); +} + +/***************************************************************************** +* Function: xsvfDoSDRMasking +* Description: Update the data value with the next XSDRINC data and address. +* Example: dataVal=0x01ff, nextData=0xab, addressMask=0x0100, +* dataMask=0x00ff, should set dataVal to 0x02ab +* Parameters: plvTdi - The current TDI value. +* plvNextData - the next data value. +* plvAddressMask - the address mask. +* plvDataMask - the data mask. +* Returns: void. +*****************************************************************************/ +#ifdef XSVF_SUPPORT_COMPRESSION +void xsvfDoSDRMasking( lenVal* plvTdi, + lenVal* plvNextData, + lenVal* plvAddressMask, + lenVal* plvDataMask ) +{ + int i; + unsigned char ucTdi; + unsigned char ucTdiMask; + unsigned char ucDataMask; + unsigned char ucNextData; + unsigned char ucNextMask; + short sNextData; + + /* add the address Mask to dataVal and return as a new dataVal */ + addVal( plvTdi, plvTdi, plvAddressMask ); + + ucNextData = 0; + ucNextMask = 0; + sNextData = plvNextData->len; + for ( i = plvDataMask->len - 1; i >= 0; --i ) + { + /* Go through data mask in reverse order looking for mask (1) bits */ + ucDataMask = plvDataMask->val[ i ]; + if ( ucDataMask ) + { + /* Retrieve the corresponding TDI byte value */ + ucTdi = plvTdi->val[ i ]; + + /* For each bit in the data mask byte, look for 1's */ + ucTdiMask = 1; + while ( ucDataMask ) + { + if ( ucDataMask & 1 ) + { + if ( !ucNextMask ) + { + /* Get the next data byte */ + ucNextData = plvNextData->val[ --sNextData ]; + ucNextMask = 1; + } + + /* Set or clear the data bit according to the next data */ + if ( ucNextData & ucNextMask ) + { + ucTdi |= ucTdiMask; /* Set bit */ + } + else + { + ucTdi &= ( ~ucTdiMask ); /* Clear bit */ + } + + /* Update the next data */ + ucNextMask <<= 1; + } + ucTdiMask <<= 1; + ucDataMask >>= 1; + } + + /* Update the TDI value */ + plvTdi->val[ i ] = ucTdi; + } + } +} +#endif /* XSVF_SUPPORT_COMPRESSION */ + +/*============================================================================ +* XSVF Command Functions (type = TXsvfDoCmdFuncPtr) +* These functions update pXsvfInfo->iErrorCode only on an error. +* Otherwise, the error code is left alone. +* The function returns the error code from the function. +============================================================================*/ + +/***************************************************************************** +* Function: xsvfDoIllegalCmd +* Description: Function place holder for illegal/unsupported commands. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ) +{ + XSVFDBG_PRINTF2( 0, "ERROR: Encountered unsupported command #%d (%s)\n", + ((unsigned int)(pXsvfInfo->ucCommand)), + ((pXsvfInfo->ucCommand < XLASTCMD) + ? (xsvf_pzCommandName[pXsvfInfo->ucCommand]) + : "Unknown") ); + pXsvfInfo->iErrorCode = XSVF_ERROR_ILLEGALCMD; + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXCOMPLETE +* Description: XCOMPLETE (no parameters) +* Update complete status for XSVF player. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo ) +{ + pXsvfInfo->ucComplete = 1; + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** +* Function: xsvfDoXTDOMASK +* Description: XTDOMASK +* Prespecify the TDO compare mask. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo ) +{ + readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes ); + XSVFDBG_PRINTF( 4, " TDO Mask = "); + XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) ); + XSVFDBG_PRINTF( 4, "\n"); + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** +* Function: xsvfDoXSIR +* Description: XSIR <(byte)shiftlen> +* Get the instruction and shift the instruction into the TAP. +* If prespecified XRUNTEST!=0, goto RUNTEST and wait after +* the shift for XRUNTEST usec. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSIR( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucShiftIrBits; + short sShiftIrBytes; + int iErrorCode; + + /* Get the shift length and store */ + readByte( &ucShiftIrBits ); + sShiftIrBytes = xsvfGetAsNumBytes( ucShiftIrBits ); + XSVFDBG_PRINTF1( 3, " XSIR length = %d\n", + ((unsigned int)ucShiftIrBits) ); + + if ( sShiftIrBytes > MAX_LEN ) + { + iErrorCode = XSVF_ERROR_DATAOVERFLOW; + } + else + { + /* Get and store instruction to shift in */ + readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) ); + + /* Shift the data */ + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR, + ucShiftIrBits, &(pXsvfInfo->lvTdi), + /*plvTdoCaptured*/0, /*plvTdoExpected*/0, + /*plvTdoMask*/0, pXsvfInfo->ucEndIR, + pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 ); + } + + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXSIR2 +* Description: XSIR <(2-byte)shiftlen> +* Get the instruction and shift the instruction into the TAP. +* If prespecified XRUNTEST!=0, goto RUNTEST and wait after +* the shift for XRUNTEST usec. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo ) +{ + long lShiftIrBits; + short sShiftIrBytes; + int iErrorCode; + + /* Get the shift length and store */ + readVal( &(pXsvfInfo->lvTdi), 2 ); + lShiftIrBits = value( &(pXsvfInfo->lvTdi) ); + sShiftIrBytes = xsvfGetAsNumBytes( lShiftIrBits ); + XSVFDBG_PRINTF1( 3, " XSIR2 length = %d\n", lShiftIrBits); + + if ( sShiftIrBytes > MAX_LEN ) + { + iErrorCode = XSVF_ERROR_DATAOVERFLOW; + } + else + { + /* Get and store instruction to shift in */ + readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) ); + + /* Shift the data */ + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR, + lShiftIrBits, &(pXsvfInfo->lvTdi), + /*plvTdoCaptured*/0, /*plvTdoExpected*/0, + /*plvTdoMask*/0, pXsvfInfo->ucEndIR, + pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 ); + } + + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXSDR +* Description: XSDR +* Shift the given TDI data into the JTAG scan chain. +* Compare the captured TDO with the expected TDO from the +* previous XSDRTDO command using the previously specified +* XTDOMASK. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSDR( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes ); + /* use TDOExpected from last XSDRTDO instruction */ + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR, + pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXRUNTEST +* Description: XRUNTEST +* Prespecify the XRUNTEST wait time for shift operations. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo ) +{ + readVal( &(pXsvfInfo->lvTdi), 4 ); + pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) ); + XSVFDBG_PRINTF1( 3, " XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime ); + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** +* Function: xsvfDoXREPEAT +* Description: XREPEAT +* Prespecify the maximum number of XC9500/XL retries. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo ) +{ + readByte( &(pXsvfInfo->ucMaxRepeat) ); + XSVFDBG_PRINTF1( 3, " XREPEAT = %d\n", + ((unsigned int)(pXsvfInfo->ucMaxRepeat)) ); + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** +* Function: xsvfDoXSDRSIZE +* Description: XSDRSIZE +* Prespecify the XRUNTEST wait time for shift operations. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + iErrorCode = XSVF_ERROR_NONE; + readVal( &(pXsvfInfo->lvTdi), 4 ); + pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) ); + pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits ); + XSVFDBG_PRINTF1( 3, " XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits ); + if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN ) + { + iErrorCode = XSVF_ERROR_DATAOVERFLOW; + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXSDRTDO +* Description: XSDRTDO +* Get the TDI and expected TDO values. Then, shift. +* Compare the expected TDO with the captured TDO using the +* prespecified XTDOMASK. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), + pXsvfInfo->lShiftLengthBits, + pXsvfInfo->sShiftLengthBytes, + &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), + pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, + pXsvfInfo->ucMaxRepeat ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXSETSDRMASKS +* Description: XSETSDRMASKS +* +* Get the prespecified address and data mask for the XSDRINC +* command. +* Used for xc9500/xl compressed XSVF data. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +#ifdef XSVF_SUPPORT_COMPRESSION +int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo ) +{ + /* read the addressMask */ + readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes ); + /* read the dataMask */ + readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes ); + + XSVFDBG_PRINTF( 4, " Address Mask = " ); + XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) ); + XSVFDBG_PRINTF( 4, "\n" ); + XSVFDBG_PRINTF( 4, " Data Mask = " ); + XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) ); + XSVFDBG_PRINTF( 4, "\n" ); + + return( XSVF_ERROR_NONE ); +} +#endif /* XSVF_SUPPORT_COMPRESSION */ + +/***************************************************************************** +* Function: xsvfDoXSDRINC +* Description: XSDRINC +* ... +* Get the XSDRINC parameters and execute the XSDRINC command. +* XSDRINC starts by loading the first TDI shift value. +* Then, for numTimes, XSDRINC gets the next piece of data, +* replaces the bits from the starting TDI as defined by the +* XSETSDRMASKS.dataMask, adds the address mask from +* XSETSDRMASKS.addressMask, shifts the new TDI value, +* and compares the TDO to the expected TDO from the previous +* XSDRTDO command using the XTDOMASK. +* Used for xc9500/xl compressed XSVF data. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +#ifdef XSVF_SUPPORT_COMPRESSION +int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + int iDataMaskLen; + unsigned char ucDataMask; + unsigned char ucNumTimes; + unsigned char i; + + readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes ); + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR, + pXsvfInfo->lShiftLengthBits, + &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat ); + if ( !iErrorCode ) + { + /* Calculate number of data mask bits */ + iDataMaskLen = 0; + for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i ) + { + ucDataMask = pXsvfInfo->lvDataMask.val[ i ]; + while ( ucDataMask ) + { + iDataMaskLen += ( ucDataMask & 1 ); + ucDataMask >>= 1; + } + } + + /* Get the number of data pieces, i.e. number of times to shift */ + readByte( &ucNumTimes ); + + /* For numTimes, get data, fix TDI, and shift */ + for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i ) + { + readVal( &(pXsvfInfo->lvNextData), + xsvfGetAsNumBytes( iDataMaskLen ) ); + xsvfDoSDRMasking( &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvNextData), + &(pXsvfInfo->lvAddressMask), + &(pXsvfInfo->lvDataMask) ); + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), + XTAPSTATE_SHIFTDR, + pXsvfInfo->lShiftLengthBits, + &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), + pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, + pXsvfInfo->ucMaxRepeat ); + } + } + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} +#endif /* XSVF_SUPPORT_COMPRESSION */ + +/***************************************************************************** +* Function: xsvfDoXSDRBCE +* Description: XSDRB/XSDRC/XSDRE +* If not already in SHIFTDR, goto SHIFTDR. +* Shift the given TDI data into the JTAG scan chain. +* Ignore TDO. +* If cmd==XSDRE, then goto ENDDR. Otherwise, stay in ShiftDR. +* XSDRB, XSDRC, and XSDRE are the same implementation. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucEndDR; + int iErrorCode; + ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ? + pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR); + iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), + pXsvfInfo->lShiftLengthBits, + pXsvfInfo->sShiftLengthBytes, + &(pXsvfInfo->lvTdi), + /*plvTdoCaptured*/0, /*plvTdoExpected*/0, + /*plvTdoMask*/0, ucEndDR, + /*lRunTestTime*/0, /*ucMaxRepeat*/0 ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXSDRTDOBCE +* Description: XSDRB/XSDRC/XSDRE +* If not already in SHIFTDR, goto SHIFTDR. +* Shift the given TDI data into the JTAG scan chain. +* Compare TDO, but do NOT use XTDOMASK. +* If cmd==XSDRTDOE, then goto ENDDR. Otherwise, stay in ShiftDR. +* XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucEndDR; + int iErrorCode; + ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ? + pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR); + iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), + pXsvfInfo->lShiftLengthBits, + pXsvfInfo->sShiftLengthBytes, + &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + /*plvTdoMask*/0, ucEndDR, + /*lRunTestTime*/0, /*ucMaxRepeat*/0 ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXSTATE +* Description: XSTATE +* == XTAPSTATE; +* Get the state parameter and transition the TAP to that state. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucNextState; + int iErrorCode; + readByte( &ucNextState ); + iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXENDXR +* Description: XENDIR/XENDDR +* : 0 = RUNTEST; 1 = PAUSE. +* Get the prespecified XENDIR or XENDDR. +* Both XENDIR and XENDDR use the same implementation. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + unsigned char ucEndState; + + iErrorCode = XSVF_ERROR_NONE; + readByte( &ucEndState ); + if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) ) + { + iErrorCode = XSVF_ERROR_ILLEGALSTATE; + } + else + { + + if ( pXsvfInfo->ucCommand == XENDIR ) + { + if ( ucEndState == XENDXR_RUNTEST ) + { + pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST; + } + else + { + pXsvfInfo->ucEndIR = XTAPSTATE_PAUSEIR; + } + XSVFDBG_PRINTF1( 3, " ENDIR State = %s\n", + xsvf_pzTapState[ pXsvfInfo->ucEndIR ] ); + } + else /* XENDDR */ + { + if ( ucEndState == XENDXR_RUNTEST ) + { + pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST; + } + else + { + pXsvfInfo->ucEndDR = XTAPSTATE_PAUSEDR; + } + XSVFDBG_PRINTF1( 3, " ENDDR State = %s\n", + xsvf_pzTapState[ pXsvfInfo->ucEndDR ] ); + } + } + + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXCOMMENT +* Description: XCOMMENT +* == text comment; +* Arbitrary comment embedded in the XSVF. +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo ) +{ + /* Use the comment for debugging */ + /* Otherwise, read through the comment to the end '\0' and ignore */ + unsigned char ucText; + +#ifdef DEBUG_MODE + if ( xsvf_iDebugLevel > 0 ) + { + putchar( ' ' ); + } +#endif + + do + { + readByte( &ucText ); +#ifdef DEBUG_MODE + if ( xsvf_iDebugLevel > 0 ) + { + putchar( ucText ? ucText : '\n' ); + } +#endif + } while ( ucText ); + + pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXWAIT +* Description: XWAIT +* If not already in , then go to . +* Wait in for microseconds. +* Finally, if not already in , then goto . +* Parameters: pXsvfInfo - XSVF information pointer. +* Returns: int - 0 = success; non-zero = error. +*****************************************************************************/ +int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucWaitState; + unsigned char ucEndState; + long lWaitTime; + + /* Get Parameters */ + /* */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucWaitState = pXsvfInfo->lvTdi.val[0]; + + /* */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucEndState = pXsvfInfo->lvTdi.val[0]; + + /* */ + readVal( &(pXsvfInfo->lvTdi), 4 ); + lWaitTime = value( &(pXsvfInfo->lvTdi) ); + XSVFDBG_PRINTF2( 3, " XWAIT: state = %s; time = %ld\n", + xsvf_pzTapState[ ucWaitState ], lWaitTime ); + + /* If not already in , go to */ + if ( pXsvfInfo->ucTapState != ucWaitState ) + { + xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState ); + } + + /* Wait for microseconds */ + waitTime( lWaitTime ); + + /* If not already in , go to */ + if ( pXsvfInfo->ucTapState != ucEndState ) + { + xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState ); + } + + return( XSVF_ERROR_NONE ); +} + + +/*============================================================================ +* Execution Control Functions +============================================================================*/ + +/***************************************************************************** +* Function: xsvfInitialize +* Description: Initialize the xsvf player. +* Call this before running the player to initialize the data +* in the SXsvfInfo struct. +* xsvfCleanup is called to clean up the data in SXsvfInfo +* after the XSVF is played. +* Parameters: pXsvfInfo - ptr to the XSVF information. +* Returns: int - 0 = success; otherwise error. +*****************************************************************************/ +int xsvfInitialize( SXsvfInfo* pXsvfInfo ) +{ + /* Initialize values */ + pXsvfInfo->iErrorCode = xsvfInfoInit( pXsvfInfo ); + + if ( !pXsvfInfo->iErrorCode ) + { + /* Initialize the TAPs */ + pXsvfInfo->iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), + XTAPSTATE_RESET ); + } + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfRun +* Description: Run the xsvf player for a single command and return. +* First, call xsvfInitialize. +* Then, repeatedly call this function until an error is detected +* or until the pXsvfInfo->ucComplete variable is non-zero. +* Finally, call xsvfCleanup to cleanup any remnants. +* Parameters: pXsvfInfo - ptr to the XSVF information. +* Returns: int - 0 = success; otherwise error. +*****************************************************************************/ +int xsvfRun( SXsvfInfo* pXsvfInfo ) +{ + /* Process the XSVF commands */ + if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) ) + { + /* read 1 byte for the instruction */ + readByte( &(pXsvfInfo->ucCommand) ); + ++(pXsvfInfo->lCommandCount); + + if ( pXsvfInfo->ucCommand < XLASTCMD ) + { + /* Execute the command. Func sets error code. */ + XSVFDBG_PRINTF1( 2, " %s\n", + xsvf_pzCommandName[pXsvfInfo->ucCommand] ); + /* If your compiler cannot take this form, + then convert to a switch statement */ + xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo ); + } + else + { + /* Illegal command value. Func sets error code. */ + xsvfDoIllegalCmd( pXsvfInfo ); + } + } + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfCleanup +* Description: cleanup remnants of the xsvf player. +* Parameters: pXsvfInfo - ptr to the XSVF information. +* Returns: void. +*****************************************************************************/ +void xsvfCleanup( SXsvfInfo* pXsvfInfo ) +{ + xsvfInfoCleanup( pXsvfInfo ); +} + + +/*============================================================================ +* xsvfExecute() - The primary entry point to the XSVF player +============================================================================*/ + +/***************************************************************************** +* Function: xsvfExecute +* Description: Process, interpret, and apply the XSVF commands. +* See port.c:readByte for source of XSVF data. +* Parameters: none. +* Returns: int - Legacy result values: 1 == success; 0 == failed. +*****************************************************************************/ +int xsvfExecute() +{ + SXsvfInfo xsvfInfo; + + xsvfInitialize( &xsvfInfo ); + + while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) ) + { + xsvfRun( &xsvfInfo ); + } + + if ( xsvfInfo.iErrorCode ) + { + XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[ + ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST ) + ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] ); + XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld. See line #%ld in the XSVF ASCII file.\n", + xsvfInfo.lCommandCount, xsvfInfo.lCommandCount ); + } + else + { + XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" ); + } + + xsvfCleanup( &xsvfInfo ); + + return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); +} + + +/*============================================================================ +* main +============================================================================*/ + +/***************************************************************************** +* Function: main +* Description: main function. +* Specified here for creating stand-alone debug executable. +* Embedded users should call xsvfExecute() directly. +* Parameters: iArgc - number of command-line arguments. +* ppzArgv - array of ptrs to strings (command-line arguments). +* Returns: int - Legacy return value: 1 = success; 0 = error. +*****************************************************************************/ +#ifdef XSVF_MAIN +int main( int iArgc, char** ppzArgv ) +{ + int iErrorCode; + char* pzXsvfFileName; + int i; + clock_t startClock; + clock_t endClock; + + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); + pzXsvfFileName = 0; + + printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION ); + + for ( i = 1; i < iArgc ; ++i ) + { + if ( !_stricmp( ppzArgv[ i ], "-v" ) ) + { + ++i; + if ( i >= iArgc ) + { + printf( "ERROR: missing parameter for -v option.\n" ); + } + else + { + xsvf_iDebugLevel = atoi( ppzArgv[ i ] ); + printf( "Verbose level = %d\n", xsvf_iDebugLevel ); + } + } + else + { + pzXsvfFileName = ppzArgv[ i ]; + printf( "XSVF file = %s\n", pzXsvfFileName ); + } + } + + if ( !pzXsvfFileName ) + { + printf( "USAGE: playxsvf [-v level] filename.xsvf\n" ); + printf( "where: -v level = verbose, level = 0-4 (default=0)\n" ); + printf( " filename.xsvf = the XSVF file to execute.\n" ); + } + else + { + /* read from the XSVF file instead of a real prom */ + in = fopen( pzXsvfFileName, "rb" ); + if ( !in ) + { + printf( "ERROR: Cannot open file %s\n", pzXsvfFileName ); + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN ); + } + else + { + /* Initialize the I/O. SetPort initializes I/O on first call */ + setPort( TMS, 1 ); + + /* Execute the XSVF in the file */ + startClock = clock(); + iErrorCode = xsvfExecute(); + endClock = clock(); + fclose( in ); + printf( "Execution Time = %.3f seconds\n", + (((double)(endClock - startClock))/CLOCKS_PER_SEC) ); + } + } + + return( iErrorCode ); +} +#endif /* XSVF_MAIN */ + diff --git a/source-1.0L-F11/AVR/xsvf/micro.h b/source-1.0L-F11/AVR/xsvf/micro.h new file mode 100755 index 0000000..4c99ca6 --- /dev/null +++ b/source-1.0L-F11/AVR/xsvf/micro.h @@ -0,0 +1,42 @@ +/***************************************************************************** +* File: micro.h +* Description: This header file contains the function prototype to the +* primary interface function for the XSVF player. +* Usage: FIRST - PORTS.C +* Customize the ports.c function implementations to establish +* the correct protocol for communicating with your JTAG ports +* (setPort() and readTDOBit()) and tune the waitTime() delay +* function. Also, establish access to the XSVF data source +* in the readByte() function. +* FINALLY - Call xsvfExecute(). +*****************************************************************************/ +#ifndef XSVF_MICRO_H +#define XSVF_MICRO_H + +/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ +#define XSVF_LEGACY_SUCCESS 1 +#define XSVF_LEGACY_ERROR 0 + +/* 4.04 [NEW] Error codes for xsvfExecute. */ +/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */ +#define XSVF_ERROR_NONE 0 +#define XSVF_ERROR_UNKNOWN 1 +#define XSVF_ERROR_TDOMISMATCH 2 +#define XSVF_ERROR_MAXRETRIES 3 /* TDO mismatch after max retries */ +#define XSVF_ERROR_ILLEGALCMD 4 +#define XSVF_ERROR_ILLEGALSTATE 5 +#define XSVF_ERROR_DATAOVERFLOW 6 /* Data > lenVal MAX_LEN buffer size*/ +/* Insert new errors here */ +#define XSVF_ERROR_LAST 7 + +/***************************************************************************** +* Function: xsvfExecute +* Description: Process, interpret, and apply the XSVF commands. +* See port.c:readByte for source of XSVF data. +* Parameters: none. +* Returns: int - For error codes see above. +*****************************************************************************/ +extern int xsvfExecute(); + +#endif /* XSVF_MICRO_H */ + diff --git a/source-1.0L-F11/AVR/xsvf/ports.cpp b/source-1.0L-F11/AVR/xsvf/ports.cpp new file mode 100755 index 0000000..9cb23b8 --- /dev/null +++ b/source-1.0L-F11/AVR/xsvf/ports.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include "ports.h" + +#define TMS_PORT PORTC +#define TMS_PIN 3 + +#define TCK_PORT PORTC +#define TCK_PIN 2 + +#define TDO_PORT PINC +#define TDO_PIN 4 + +#define TDI_PORT PORTC +#define TDI_PIN 5 + +/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ +void setPort(short p,short val) +{ + if (p==TMS) + { + if (val) + TMS_PORT |= (1<= 50L ) + { + /* Make sure TCK is low during wait for XC18V00/XCFxxS */ + /* Or, a running TCK implementation as shown above is an OK alternate */ + setPort( TCK, 0 ); + + /* Use Windows Sleep(). Round up to the nearest millisec */ + _sleep( ( microsec + 999L ) / 1000L ); + } + else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ + { + for ( i = 0; i < microsec; ++i ) + { + pulseClock(); + } + } +#endif + +#if 0 + /* Alternate implementation */ + /* This implementation is valid for only XC9500/XL/XV, CoolRunner/II CPLDs, + XC18V00 PROMs, or Platform Flash XCFxxS/XCFxxP PROMs. + This implementation does not work with FPGAs JTAG configuration. */ + /* Make sure TCK is low during wait for XC18V00/XCFxxS PROMs */ + /* Or, a running TCK implementation as shown above is an OK alternate */ + setPort( TCK, 0 ); + /* Use Windows Sleep(). Round up to the nearest millisec */ + _sleep( ( microsec + 999L ) / 1000L ); +#endif +} diff --git a/source-1.0L-F11/AVR/xsvf/ports.h b/source-1.0L-F11/AVR/xsvf/ports.h new file mode 100755 index 0000000..5ac0cfc --- /dev/null +++ b/source-1.0L-F11/AVR/xsvf/ports.h @@ -0,0 +1,36 @@ +/*******************************************************/ +/* file: ports.h */ +/* abstract: This file contains extern declarations */ +/* for providing stimulus to the JTAG ports.*/ +/*******************************************************/ + +#ifndef ports_dot_h +#define ports_dot_h + +/* these constants are used to send the appropriate ports to setPort */ +/* they should be enumerated types, but some of the microcontroller */ +/* compilers don't like enumerated types */ +#define TCK (short) 0 +#define TMS (short) 1 +#define TDI (short) 2 + +/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ +extern void setPort(short p, short val); + +/* read the TDO bit and store it in val */ +extern unsigned char readTDOBit(); + +/* make clock go down->up->down*/ +extern void pulseClock(); + +/* read the next byte of data from the xsvf file */ +extern void readByte(unsigned char *data); + +extern void waitTime(long microsec); + +/* set the callback function used to read the next byte of the xsvf data */ +typedef unsigned char (*ReadFuncPtr)(void); +extern void setReadCallback(ReadFuncPtr p); + + +#endif diff --git a/source-1.0L-F11/CPLD-Xilinx/firmware.xvf b/source-1.0L-F11/CPLD-Xilinx/firmware.xvf new file mode 100755 index 0000000..443eb73 Binary files /dev/null and b/source-1.0L-F11/CPLD-Xilinx/firmware.xvf differ diff --git a/source-1.0L-F11/CPLD-Xilinx/floppyemu.prj b/source-1.0L-F11/CPLD-Xilinx/floppyemu.prj new file mode 100755 index 0000000..08e89be --- /dev/null +++ b/source-1.0L-F11/CPLD-Xilinx/floppyemu.prj @@ -0,0 +1 @@ +verilog work "floppyemu.v" diff --git a/source-1.0L-F11/CPLD-Xilinx/floppyemu.ucf b/source-1.0L-F11/CPLD-Xilinx/floppyemu.ucf new file mode 100755 index 0000000..56ecd5a --- /dev/null +++ b/source-1.0L-F11/CPLD-Xilinx/floppyemu.ucf @@ -0,0 +1,41 @@ +#PACE: Start of Constraints generated by PACE +#PACE: Start of PACE I/O Pin Assignments +NET "stepAck_diskInserted" LOC = "P8" ; +NET "_enable" LOC = "P20" ; +NET "_rst" LOC = "P37" ; +NET "_wreq" LOC = "P18" ; +NET "_wreqMCU" LOC = "P5" ; +NET "byteReady_tk0" LOC = "P7" ; +NET "ca0" LOC = "P12" ; +NET "ca1" LOC = "P13" ; +NET "ca2" LOC = "P14" ; +NET "clk" LOC = "P43" ; +NET "data<0>" LOC = "P31" ; +NET "data<1>" LOC = "P32" ; +NET "data<2>" LOC = "P33" ; +NET "data<3>" LOC = "P34" ; +NET "data<4>" LOC = "P36" ; +NET "data<5>" LOC = "P38" ; +NET "data<6>" LOC = "P41" ; +NET "driveCurrentSide" LOC = "P3" ; +NET "stepDirectionMotorOn" LOC = "P1" ; +NET "driveTach" LOC = "P28" ; +NET "ejectRequest" LOC = "P30" ; +NET "led" LOC = "P40" ; +NET "lstrb" LOC = "P16" ; +NET "outputEnable" LOC = "P2" ; +NET "rd" LOC = "P21" ; +NET "rdAckWrTick" LOC = "P44" ; +NET "SEL" LOC = "P19" ; +NET "stepRequest" LOC = "P39" ; +NET "wr" LOC = "P22" ; +NET "zero" LOC = "P6" ; +NET "pwm" LOC = "P23" ; +NET "test" LOC = "P27" ; + +#PACE: Start of PACE Area Constraints +#PACE: Start of PACE Prohibit Constraints +#PACE: End of Constraints generated by PACE +#Created by Constraints Editor (xc9572xl-vq44-10) - 2013/11/07 +NET "clk" TNM_NET = clk; +TIMESPEC TS_clk = PERIOD "clk" 50 ns HIGH 50%; diff --git a/source-1.0L-F11/CPLD-Xilinx/floppyemu.v b/source-1.0L-F11/CPLD-Xilinx/floppyemu.v new file mode 100755 index 0000000..7721945 --- /dev/null +++ b/source-1.0L-F11/CPLD-Xilinx/floppyemu.v @@ -0,0 +1,433 @@ +/* + Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved. + + Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported + license. (CC BY-NC 3.0) The terms of the license may be viewed at + http://creativecommons.org/licenses/by-nc/3.0/ + + Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/ + + Permissions beyond the scope of this license may be available at www.bigmessowires.com + or from mailto:steve@bigmessowires.com. + + -------------------------------------------------------------------------------------- + + Disk registers (read): + State-control lines Register + CA2 CA1 CA0 SEL addressed Information in register + + 0 0 0 0 DIRTN Head step direction (0 = toward track 79, 1 = toward track 0) + 0 0 0 1 CSTIN Disk in place (0 = disk is inserted) + 0 0 1 0 STEP Drive head stepping (setting to 0 performs a step, returns to 1 when step is complete) + 0 0 1 1 WRTPRT Disk locked (0 = locked) + 0 1 0 0 MOTORON Drive motor running (0 = on, 1 = off) + 0 1 0 1 TK0 Head at track 0 (0 = at track 0) + 0 1 1 0 SWITCHED Disk switched (1 = yes?) SWIM3: relax, also eject in progress + 0 1 1 1 TACH GCR: Tachometer (produces 60 pulses for each rotation of the drive motor), MFM: Index pulse + 1 0 0 0 RDDATA0 Read data, lower head, side 0 + 1 0 0 1 RDDATA1 Read data, upper head, side 1 + 1 0 1 0 SUPERDR Drive is a Superdrive (0 = no, 1 = yes) SWIM3: two meg drive. + 1 0 1 1 MFM_MODE SWIM3: MFM_MODE, 1 = yes (opposite of writing?) + 1 1 0 0 SIDES Single- or double-sided drive (0 = single side, 1 = double side), SWIM: 0 = 4MB, 1 = not 4MB + 1 1 0 1 READY 0 = yes, SWIM3: SEEK_COMPLETE + 1 1 1 0 INSTALLED 0 = yes, only used by SWIM, not IWM? SWIM3: drive present. + 1 1 1 1 HSHK_HD 400K/800K: implements ready handshake if 1, Superdrive: Inserted disk capacity (0 = HD, 1 = DD), SWIM3: 1 = ONE_MEG_MEDIA + + + Disk registers (write): + Control lines Register + CA1 CA0 SEL addressed Register function + + 0 0 0 DIRTN Set stepping direction (0 = toward track 79, 1 = toward track 0), SWIM3: SEEK_POSITIVE + 0 0 1 SWITCHED Reset disk switched flag (writing 1 sets switch flag to 0) + 0 1 0 STEP Step the drive head one track (setting to 0 performs a step, returns to 1 when step is complete) + 1 0 0 MOTORON Turn drive motor on/off (0 = on, 1 = off) + 1 0 0 TWOMEGMEDIA_CHECK The first time zero is written, changes the behavior when reading SIDES + 0 1 1 MFM_MODE 0 = MFM, 1 = GCR + 1 1 0 EJECT Eject the disk (writing 1 ejects the disk) + 1 1 0 INDEX if writing 0 +*/ + +`define DRIVE_REG_DIRTN 0 +`define DRIVE_REG_CSTIN 1 +`define DRIVE_REG_STEP 2 +`define DRIVE_REG_WRTPRT 3 +`define DRIVE_REG_MOTORON 4 +`define DRIVE_REG_TK0 5 +`define DRIVE_REG_EJECT 6 +`define DRIVE_REG_TACH 7 +`define DRIVE_REG_RDDATA0 8 +`define DRIVE_REG_RDDATA1 9 +`define DRIVE_REG_SUPERDR 10 +`define DRIVE_REG_UNUSED 11 +`define DRIVE_REG_SIDES 12 +`define DRIVE_REG_READY 13 +`define DRIVE_REG_INSTALLED 14 +`define DRIVE_REG_HSHK_HD 15 + +`define FIRMWARE_VERSION_NUMBER 11 + +module floppyemu( + input clk, + + // Macintosh interface + input ca0, // PH0 + input ca1, // PH1 + input ca2, // PH2 + input lstrb, // PH3 + input SEL, // HDSEL from VIA + input _enable, + input wr, + input _wreq, + input pwm, // unused + output rd, + + // microcontroller interface + input _rst, + + output stepDirectionMotorOn, + output reg stepRequest, + input stepAck_diskInserted, + + output _wreqMCU, + output reg rdAckWrTick, + output reg driveCurrentSide, + output reg ejectRequest, + + input driveTach, + input byteReady_tk0, + + input outputEnable, + inout [6:0] data, + + output zero, + + // status display + output led, + + // debugging + output test +); + + /********** drive state data **********/ + reg _driveRegTK0; + reg _driveRegMotorOn; + reg driveRegStepDirection; + reg _driveRegWriteProtect; + reg _driveRegDiskInserted; + reg _driveRegMFMMode; + + /********** serial to parallel interface **********/ + // GCR: One bit every 2 microseconds + // The exact rate on the Macintosh is actually 16 clocks @ 7.8336 MHz = 2.04 microseconds. + // MFM: One bit every 1 microsecond + reg [7:0] shifter; + reg [5:0] bitTimer; + reg [3:0] bitCounter; + reg [6:0] wrData; + reg rdHead; + reg [1:0] wrHistory; + reg mfmWriteSynced; + reg wrClear; + + always @(posedge clk) begin + wrHistory <= { wrHistory[0], wr }; + end + + always @(posedge clk or negedge _rst) begin + if (_rst == 0) begin + rdAckWrTick <= 0; + _driveRegWriteProtect <= 1; + _driveRegDiskInserted <= 1; + _driveRegMFMMode <= 1; + wrData <= `FIRMWARE_VERSION_NUMBER; + mfmWriteSynced <= 0; + wrClear <= 0; + end + else begin + // one-way switch for disk inserted register - until next reset, stepAck_diskInserted will act only as stepAck + if (_driveRegDiskInserted == 1 && stepAck_diskInserted == 0) begin + _driveRegDiskInserted <= 0; + end + // is the Macintosh currently writing to the disk? + if (_wreq == 0) begin + // was there a transition on the wr line? + // GCR: any transition + // MFM: falling edge + if (((wrHistory[1] != wrHistory[0]) && (_driveRegMFMMode == 1)) || + ((wrHistory[1] && ~wrHistory[0]) && (_driveRegMFMMode == 0))) begin + // has at least half a bit cell time elpased since the last cell boundary? + if ((bitTimer >= 20 && _driveRegMFMMode == 1) || + (bitTimer >= 10 && _driveRegMFMMode == 0)) begin + shifter <= { shifter[6:0], 1'b1 }; + bitCounter <= bitCounter - 1'b1; + end + // do nothing if the clock count was less than half a cell + + // reset the bit timer + bitTimer <= 0; + end + else begin + // have one and a half bit cell times elapsed? + if ((bitTimer >= 60 && _driveRegMFMMode == 1) || + (bitTimer >= 30 && _driveRegMFMMode == 0)) begin + shifter <= { shifter[6:0], 1'b0 }; + bitCounter <= bitCounter - 1'b1; + + if (_driveRegMFMMode == 1) + bitTimer <= 20; + else + bitTimer <= 10; + end + else begin + // init shifter at the beginning of a write, so we can recognize the framing bits later + if (wrClear == 0) begin + shifter <= 0; + wrClear <= 1; + end + // has a complete byte been shifted in? + else if (_driveRegMFMMode == 1) begin + // GCR + if (shifter[7] == 1) begin + // GCR: The complete byte is shifter[7:0], but only 7 bits are stored in wrData, since the MSB is always 1. + wrData <= shifter[6:0]; // store the byte for the mcu + shifter <= 0; // clear the byte from the shifter + rdAckWrTick <= ~rdAckWrTick; // signal the mcu that a new byte is ready + end + end + else begin + // MFM + // If we're in write mode, but haven't yet synched (framed the bytes in the bit stream), + // and we see 01000100 in the shifter, assume that it's the first half of an A1 sync + if ((bitCounter == 0) || + (shifter == 8'h44 && mfmWriteSynced == 0)) begin + // MFM: send the mcu the data nibble in the low 4 bits, and clock bit C2 in bit 4 + wrData[0] <= shifter[0]; + wrData[1] <= shifter[2]; + wrData[2] <= shifter[4]; + wrData[3] <= shifter[6]; + wrData[4] <= shifter[5]; // clock bit + bitCounter <= 8; + + rdAckWrTick <= (shifter == 8'h44 && mfmWriteSynced == 0) ? 0 : ~rdAckWrTick; // signal the mcu that a new nibble is ready + mfmWriteSynced <= mfmWriteSynced | (shifter == 8'h44); + end + end + + bitTimer <= bitTimer + 1'b1; + end + end + end + else begin + mfmWriteSynced <= 0; + wrClear <= 0; + // is it time for a new bit? + if ((bitTimer == 40 && _driveRegMFMMode == 1) || + (bitTimer == 20 && _driveRegMFMMode == 0)) + begin + // are all the bits done? + if (bitCounter == 0) begin + // is there a new byte ready to read? + if (byteReady_tk0 == 1) begin + // if there's a byte ready, but no disk inserted, then load config options from the MCU + if (_driveRegDiskInserted == 1) begin + _driveRegWriteProtect <= data[0]; + _driveRegMFMMode <= data[1]; + end + else begin + // load the new byte. + if (_driveRegMFMMode == 1) begin + // Only 7 bits are transferred, since the MSB is always 1. + shifter <= { 1'b1, data }; + end + else begin + // For MFM, the 7 bits received from the MCU are: + // 0 0 m d3 d2 d1 d0 + // From this we can constuct the MFM-encoded byte with clock and data bits: + // c3 d3 c2 d2 c1 d1 c0 d0 + // where cN = dN+1 NOR dN. + // If m is 1, then this is part of a mark byte, and c2 should be forced to 0. + shifter[7] <= ~(shifter[7] | data[3]); + shifter[6] <= data[3]; + shifter[5] <= ~(data[3] | data[2]) & ~data[4]; + shifter[4] <= data[2]; + shifter[3] <= ~(data[2] | data[1]); + shifter[2] <= data[1]; + shifter[1] <= ~(data[1] | data[0]); + shifter[0] <= data[0]; + end + bitCounter <= 7; + rdAckWrTick <= 1; + end + end + else begin + // insert a sync byte + if (_driveRegMFMMode == 1) + begin + shifter <= { 8'b11111111 }; + bitCounter <= 9; // sync "byte" sends 10 bits rather than 8 + end + else begin + shifter <= { 8'b10101010 }; // logical 0x0, encoded 0xA. Should sync byte be 0x4E instead? + bitCounter <= 7; + end + end + end + else begin + if (bitCounter == 7) begin + // Clear rdAck after the first bit is done. This gives the microcontroller 2 microseconds + // to react to rdAck before it's deasserted. + rdAckWrTick <= 0; + end + + // there are still more bits remaining, so shift the next bit + shifter <= { shifter[6:0], 1'b0 }; // left shift + bitCounter <= bitCounter - 1'b1; + end + end + /* GCR: After the bit shift is completed, update the read head state, using the MSB of the shift register. + A logical 1 is sent as a falling (high to low) transition on the read head at a bit cell boundary time, + a logical 0 is sent as no falling transition. */ + else if (bitTimer == 2 && shifter[7] == 1 && _driveRegMFMMode == 1) begin + rdHead <= 1'b0; + end + /* GCR: Half-way through the bit cell time, set the read head to 1 + to prepare for a possible falling transition for the next bit. */ + else if (bitTimer == 20 && _driveRegMFMMode == 1) + begin + rdHead <= 1'b1; + end + /* MFM: At the start of the bit cell time, set the read head to 0 if the logical value is 1. */ + else if (bitTimer == 2 && shifter[7] == 1 && _driveRegMFMMode == 0) + begin + rdHead <= 1'b0; + end + /* MFM: About a quarter-way through the bit cell time, always reset read head to 1. */ + else if (bitTimer == 7 && _driveRegMFMMode == 0) + begin + rdHead <= 1'b1; + end + + // increment bit timer modulo 40 (20 MFM) + if ((bitTimer == 40 && _driveRegMFMMode == 1) || + (bitTimer == 20 && _driveRegMFMMode == 0)) + bitTimer <= 0; + else + bitTimer <= bitTimer + 1'b1; + end + end + end + + // enable the data output only if the MCU says its data lines are Hi Z + assign data = (outputEnable == 1) ? wrData : 7'hZZ; + + /********** register read **********/ + wire [3:0] driveReadRegisterSelect = {ca2,ca1,ca0,SEL}; + + reg registerContents; + always @* begin + case (driveReadRegisterSelect) + `DRIVE_REG_DIRTN: + registerContents = driveRegStepDirection; // step direction + `DRIVE_REG_CSTIN: + registerContents = _driveRegDiskInserted; // disk in drive, 0 = yes + `DRIVE_REG_STEP: + registerContents = ~stepRequest; // STEP, 1 = complete + `DRIVE_REG_WRTPRT: + registerContents = _driveRegWriteProtect; // write protect, 0 = on, 1 = off + `DRIVE_REG_MOTORON: + registerContents = _driveRegMotorOn; // 0 = motor on + `DRIVE_REG_TK0: + registerContents = _driveRegTK0; // TK0: track 0 indicator + `DRIVE_REG_EJECT: + registerContents = 1'b0; // disk switched? + `DRIVE_REG_TACH: + registerContents = driveTach; // TACH: 60 pulses for each rotation of the drive motor + `DRIVE_REG_RDDATA0: + registerContents = rdHead; // RDDATA0 + `DRIVE_REG_RDDATA1: + registerContents = rdHead; // RDDATA1 + `DRIVE_REG_SUPERDR: + registerContents = 1'b1; // SUPERDR, 1 = yes + `DRIVE_REG_UNUSED: + registerContents = 1'b0; // UNUSED + `DRIVE_REG_SIDES: + registerContents = 1'b1; // SIDES = double-sided drive + `DRIVE_REG_READY: + registerContents = 1'b0; // READY = yes + `DRIVE_REG_INSTALLED: + registerContents = 1'b0; // INSTALLED = yes + `DRIVE_REG_HSHK_HD: + registerContents = _driveRegMFMMode; // HSHK_HD = implements ready handshake, or DD/HD media + + endcase + end + assign rd = _enable == 1'b1 ? 1'bZ : registerContents; + + always @(posedge clk or negedge _rst) begin + if (_rst == 0) begin + driveCurrentSide = 0; + end + else if (_enable == 1'b0 && lstrb == 1'b0) begin + if (driveReadRegisterSelect == `DRIVE_REG_RDDATA0) + driveCurrentSide = 0; + else if (driveReadRegisterSelect == `DRIVE_REG_RDDATA1) + driveCurrentSide = 1; + end + end + + // compute the effective _wreq state for the microcontroller + assign _wreqMCU = ~(_wreq == 0 && _enable == 0 && _driveRegMotorOn == 0); + + // cheesy: during a step request, stepDirectionMotorOn is the step direction. Otherwise it's motorOn. + assign stepDirectionMotorOn = stepRequest ? driveRegStepDirection : _driveRegMotorOn; + + /********** register write **********/ + wire [2:0] driveWriteRegisterSelect = {ca1,ca0,SEL}; + + reg [4:0] lstrbHistory; + always @(posedge clk) begin + lstrbHistory <= { lstrbHistory[3:0], lstrb }; + end + + always @(posedge clk or negedge _rst) begin + if (_rst == 1'b0) begin + _driveRegTK0 <= 0; + _driveRegMotorOn <= 1; + driveRegStepDirection <= 0; + stepRequest <= 0; + ejectRequest <= 0; + end + // was there a rising edge on lstrb? + else if (_enable == 1'b0 && lstrbHistory == 5'b01111) begin + case (driveWriteRegisterSelect) + `DRIVE_REG_DIRTN: + driveRegStepDirection <= ca2; + //`DRIVE_REG_SWITCHED: // unused + `DRIVE_REG_STEP: + begin + stepRequest <= 1; // tell the microcontroller that a step was performed + end + `DRIVE_REG_MOTORON: + _driveRegMotorOn <= ca2; + `DRIVE_REG_EJECT: + if (ca2 == 1'b1) begin + ejectRequest <= 1; // tell the microcontroller that the disk was ejected. This stays on forever (until next reset) + end + endcase + end + else begin + // clear step request after mcu acknowledges it, and get the new track 0 state + if (stepRequest == 1 && stepAck_diskInserted == 1'b1) begin + stepRequest <= 0; + _driveRegTK0 <= byteReady_tk0; + end + end + end + + /********** Revision 1.0 board: status LEDs and fake SD writeProtect **********/ + assign led = _driveRegMotorOn; + assign zero = 0; + + +endmodule \ No newline at end of file diff --git a/source-1.0L-F11/CPLD-Xilinx/floppyemu.xise b/source-1.0L-F11/CPLD-Xilinx/floppyemu.xise new file mode 100755 index 0000000..0f0e6af --- /dev/null +++ b/source-1.0L-F11/CPLD-Xilinx/floppyemu.xise @@ -0,0 +1,210 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/source-1.0L-F11/CPLD-Xilinx/testbench.v b/source-1.0L-F11/CPLD-Xilinx/testbench.v new file mode 100755 index 0000000..55613ed --- /dev/null +++ b/source-1.0L-F11/CPLD-Xilinx/testbench.v @@ -0,0 +1,163 @@ +`timescale 1ns / 1ps + +//////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 15:13:07 11/30/2011 +// Design Name: floppyemu +// Module Name: C:/Users/steve/Documents/floppyemu/CPLD-Xilinx/testbench.v +// Project Name: floppyemu +// Target Device: +// Tool versions: +// Description: +// +// Verilog Test Fixture created by ISE for module: floppyemu +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +//////////////////////////////////////////////////////////////////////////////// + +module testbench; + + // Inputs + reg clk; + reg wr; + + // Outputs + wire [7:0] wrData; + wire rdAckWrByte; + + // Instantiate the Unit Under Test (UUT) + floppyemu uut ( + .clk(clk), + .wr(wr), + .wrData(wrData), + .rdAckWrByte(rdAckWrByte) + ); + + initial begin + clk = 0; + end + + always begin + #70 clk = 1; + #70 clk = 0; + end + + initial begin + // Initialize Inputs + wr = 0; + + // Wait 100 ns for global reset to finish + #4000; + + // send 10-bit sync byte + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + #2000 ; + + // send 10-bit sync byte + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + #2000 ; + + // send 10-bit sync byte + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + #2000 ; + + // send 10-bit sync byte + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + #2000 ; + + // send 10-bit sync byte + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + #2000 ; + + // D5 = 1101 0101 + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + + // AA = 1010 1010 + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 ; + + // 96 = 1001 0110 + #2000 wr = ~wr; + #2000 ; + #2000 ; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + + // 96 = 1001 0110 + #2000 wr = ~wr; + #2000 ; + #2000 ; + #2000 wr = ~wr; + #2000 ; + #2000 wr = ~wr; + #2000 wr = ~wr; + #2000 ; + + $stop; + end + +endmodule + diff --git a/source-1.0L-F11/eagle/floppyemu 1.1.1/board-layout.png b/source-1.0L-F11/eagle/floppyemu 1.1.1/board-layout.png new file mode 100755 index 0000000..b0e7ed3 Binary files /dev/null and b/source-1.0L-F11/eagle/floppyemu 1.1.1/board-layout.png differ diff --git a/source-1.0L-F11/eagle/floppyemu 1.1.1/board-schematic.png b/source-1.0L-F11/eagle/floppyemu 1.1.1/board-schematic.png new file mode 100755 index 0000000..a4f1df8 Binary files /dev/null and b/source-1.0L-F11/eagle/floppyemu 1.1.1/board-schematic.png differ diff --git a/source-1.0L-F11/eagle/floppyemu 1.1.1/floppyemu.brd b/source-1.0L-F11/eagle/floppyemu 1.1.1/floppyemu.brd new file mode 100755 index 0000000..bfd9c7e --- /dev/null +++ b/source-1.0L-F11/eagle/floppyemu 1.1.1/floppyemu.brd @@ -0,0 +1,4669 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +PREV +SELECT +NEXT +RESET +STATUS +ISP +LCD1 +LCD2 +CPLD +AVR +244 +X1 +R4 +R1 +R3 +C12 +C13 +C11 +1117 +MACINTOSH FLOPPY EMU +VERSION 1.2 +WWW.BIGMESSOWIRES.COM +3V3 +LED +CE +RST +D/C +MOSI +SCLK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +POWER +R5 +C10 +C8 +IC1 +IC2 +IC3 +IC4 +J1 +J2 +J3 +C2 +C1 +C3 +C9 +C4 +C6 +C5 +C7 +U1 +SD Card +DESIGNED AND PRODUCED BY +LIGHT + + + + + + + + + + + +Extra-long pads for easier hand soldering + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +Extra-long pads for easier hand soldering + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>SUB-D</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +1 +10 +11 +19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + +Omron B3FS SMD tactile switch + + + + + + + + + +> Name + + +<b>Shrink Small Outline Package</b><p> +package type SS + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +<b>CONNECTOR</b><p> +series 057 contact pc board low profile headers<p> +straight + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_R971.pdf + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +<b>Smal Outline Transistor</b> + + + + + + + + +>NAME +>VALUE + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find anything that moves- switches, relays, buttons, potentiometers. Also, anything that goes on a board but isn't electrical in nature- screws, standoffs, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + +<b>Stand Off</b><p> +This is the mechanical footprint for a #4 phillips button head screw. Use the keepout ring to avoid running the screw head into surrounding components. SKU : PRT-00447 + + + + + + + + + + +<b>Test Pins/Pads</b><p> +Cream on SMD OFF.<br> +new: Attribute TP_SIGNAL_NAME<br> +<author>Created by librarian@cadsoft.de</author> + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + +1/6W Thru-hole Resistor - *UNPROVEN* + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +<b>EAGLE Design Rules</b> +<p> +Die Standard-Design-Rules sind so gewählt, dass sie für +die meisten Anwendungen passen. Sollte ihre Platine +besondere Anforderungen haben, treffen Sie die erforderlichen +Einstellungen hier und speichern die Design Rules unter +einem neuen Namen ab. +<b>Smart Prototyping Design Rules</b> +<p> +http://smart-prototyping.com/index.php?route=product/product&product_id=142 +<b>NOA-Labs EAGLE Design Rules</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source-1.0L-F11/eagle/floppyemu 1.1.1/floppyemu.sch b/source-1.0L-F11/eagle/floppyemu 1.1.1/floppyemu.sch new file mode 100755 index 0000000..68478da --- /dev/null +++ b/source-1.0L-F11/eagle/floppyemu 1.1.1/floppyemu.sch @@ -0,0 +1,7254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Extra-long pads for easier hand soldering + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +Extra-long pads for easier hand soldering + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>SUB-D</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +1 +10 +11 +19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + +Omron B3FS SMD tactile switch + + + + + + + + + +> Name + + +<b>Shrink Small Outline Package</b><p> +package type SS + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +<b>CONNECTOR</b><p> +series 057 contact pc board low profile headers<p> +straight + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + +>NAME +VCC_INT +GND +VCC_IO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +MOSI +RESET +SCK +MISO +VCC +GND + + + + + + + + + + + + + + + +>NAME + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +GND +VCC + + + + + + + + + + + + + + + + + + + + + + +SD & MMC + + + + +<b>8-bit Microcontroller</b> with 128K Bytes In-System Programmable Flash<p> +Source: http://www.atmel.com/dyn/resources/prod_documents/doc2593.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>SUB-D</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>AVR ISP 6 Pin - Locking Pins</b> +This is the reduced ISP connector for AVR programming. Common on Arduino. This footprint will take up less PCB space and can be used with a 10-pin to 6-pin adapter such as SKU: BOB-08508 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Omron B3FS-10XX SMD tactile switch + + + + + + + + + + + + + + + + + + +<b>MEMORY</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>SD MMC Card holder</b> +<p> +4UCON part #06132 - easy to solder + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +JST crimp connector: 1mm pitch, top entry + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>Name +>Value + + + + + + + + + +>Name +>Value + + + + + + +>NAME +>VALUE + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>Name +>Value + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + +CTZ3 Series land pattern for variable capacitor - CTZ3E-50C-W1-PF + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>Name +>Value + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + + +1/6W Thru-hole Resistor - *UNPROVEN* + + + + + + +>NAME +>VALUE + + + + + + +>NAME +>VALUE + + + + +1/4W Resistor, 0.4" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +1/2W Resistor, 0.5" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +1W Resistor, 0.6" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +2W Resistor, 0.8" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>Header 8</b> +Standard 8-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Capacitor</b> +Standard 0603 ceramic capacitor, and 0.1" leaded capacitor. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Resistor</b> +Basic schematic elements and footprints for 0603, 1206, and PTH resistors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + +Low cost SMT crystals, no capacitors included +<p>http://www.ladyada.net/library/eagle</p> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE + + + + + +>VALUE + + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + + + +<b>CHICAGO MINIATURE LAMP, INC.</b><p> +7022X Series SMT LEDs 1206 Package Size + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + +<B>LED</B><p> +5 mm, square, Siemens + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<B>LED</B><p> +2 x 5 mm, rectangle + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + +<B>LED</B><p> +3 mm, round + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>LED</B><p> +5 mm, round + + + + + + + + + + + +>NAME +>VALUE + + +<B>LED</B><p> +1 mm, round, Siemens + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<B>LED BLOCK</B><p> +1 LED, Siemens + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + +A+ +K- +>NAME +>VALUE + + + + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE ++ +- + + +<B>IR LED</B><p> +infrared emitting diode, Infineon +TO-18, lead spacing 2.54 mm, cathode marking<p> +Inifineon + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>IR LED</B><p> +infrared emitting diode, Infineon +TO-18, lead spacing 2.54 mm, cathode marking<p> +Inifineon + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>LED</B><p> +rectangle, 5.7 x 3.2 mm + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>IR LED</B><p> +IR transmitter Siemens + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>TOPLED® High-optical Power LED (HOP)</b><p> +Source: http://www.osram.convergy.de/ ... ls_t675.pdf + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +A +C + + + + + + + +<b>BLUE LINETM Hyper Mini TOPLED® Hyper-Bright LED</b><p> +Source: http://www.osram.convergy.de/ ... LB M676.pdf + + + + + + + + + + + + + + +A +C +>NAME +>VALUE + + + + + + + +<b>Super SIDELED® High-Current LED</b><p> +LG A672, LP A672 <br> +Source: http://www.osram.convergy.de/ ... LG_LP_A672.pdf (2004.05.13) + + + + + + + + + + + + + + + + + + + +C +A +>NAME +>VALUE + + + + + + + +<b>SmartLEDTM Hyper-Bright LED</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY L896.pdf + + + + + + + + +>NAME +>VALUE + + + + + +<b>Hyper TOPLED® RG Hyper-Bright LED</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY T776.pdf + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +A +C + + + + + + + + + + +<b>Hyper Micro SIDELED®</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY Y876.pdf + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +<b>Power TOPLED®</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LA_LY E67B.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +C +A +C +C + + + + + + + + + + + +<b>Hyper CHIPLED Hyper-Bright LED</b><p> +LB Q993<br> +Source: http://www.osram.convergy.de/ ... Lb_q993.pdf + + + + +>NAME +>VALUE + + + + + + + +<b>Hyper CHIPLED Hyper-Bright LED</b><p> +LB R99A<br> +Source: http://www.osram.convergy.de/ ... lb_r99a.pdf + + + + +>NAME +>VALUE + + + + + + + +<b>Mini TOPLED Santana®</b><p> +Source: http://www.osram.convergy.de/ ... LG M470.pdf + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_R971.pdf + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_LY N971.pdf + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_LY Q971.pdf + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +<b>CHIPLED-0603</b><p> +Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> +Package able to withstand TTW-soldering heat<br> +Package suitable for TTW-soldering<br> +Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + +<b>SmartLED TTW</b><p> +Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> +Package able to withstand TTW-soldering heat<br> +Package suitable for TTW-soldering<br> +Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + +<b>Lumileds Lighting. LUXEON®</b> with cool pad<p> +Source: K2.pdf + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Lumileds Lighting. LUXEON®</b> without cool pad<p> +Source: K2.pdf + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +<B>LED</B><p> +10 mm, round + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>SURFACE MOUNT LED LAMP</b> 3.5x2.8mm<p> +Source: http://www.kingbright.com/manager/upload/pdf/KA-3528ASYC(Ver1189474662.1) + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + +<b>LED</b><p> +<u>OSRAM</u>:<br> + +- <u>CHIPLED</u><br> +LG R971, LG N971, LY N971, LG Q971, LY Q971, LO R971, LY R971 +LH N974, LH R974<br> +LS Q976, LO Q976, LY Q976<br> +LO Q996<br> + +- <u>Hyper CHIPLED</u><br> +LW Q18S<br> +LB Q993, LB Q99A, LB R99A<br> + +- <u>SideLED</u><br> +LS A670, LO A670, LY A670, LG A670, LP A670<br> +LB A673, LV A673, LT A673, LW A673<br> +LH A674<br> +LY A675<br> +LS A676, LA A676, LO A676, LY A676, LW A676<br> +LS A679, LY A679, LG A679<br> + +- <u>Hyper Micro SIDELED®</u><br> +LS Y876, LA Y876, LO Y876, LY Y876<br> +LT Y87S<br> + +- <u>SmartLED</u><br> +LW L88C, LW L88S<br> +LB L89C, LB L89S, LG L890<br> +LS L89K, LO L89K, LY L89K<br> +LS L896, LA L896, LO L896, LY L896<br> + +- <u>TOPLED</u><br> +LS T670, LO T670, LY T670, LG T670, LP T670<br> +LSG T670, LSP T670, LSY T670, LOP T670, LYG T670<br> +LG T671, LOG T671, LSG T671<br> +LB T673, LV T673, LT T673, LW T673<br> +LH T674<br> +LS T676, LA T676, LO T676, LY T676, LB T676, LH T676, LSB T676, LW T676<br> +LB T67C, LV T67C, LT T67C, LS T67K, LO T67K, LY T67K, LW E67C<br> +LS E67B, LA E67B, LO E67B, LY E67B, LB E67C, LV E67C, LT E67C<br> +LW T67C<br> +LS T679, LY T679, LG T679<br> +LS T770, LO T770, LY T770, LG T770, LP T770<br> +LB T773, LV T773, LT T773, LW T773<br> +LH T774<br> +LS E675, LA E675, LY E675, LS T675<br> +LS T776, LA T776, LO T776, LY T776, LB T776<br> +LHGB T686<br> +LT T68C, LB T68C<br> + +- <u>Hyper Mini TOPLED®</u><br> +LB M676<br> + +- <u>Mini TOPLED Santana®</u><br> +LG M470<br> +LS M47K, LO M47K, LY M47K +<p> +Source: http://www.osram.convergy.de<p> + +<u>LUXEON:</u><br> +- <u>LUMILED®</u><br> +LXK2-PW12-R00, LXK2-PW12-S00, LXK2-PW14-U00, LXK2-PW14-V00<br> +LXK2-PM12-R00, LXK2-PM12-S00, LXK2-PM14-U00<br> +LXK2-PE12-Q00, LXK2-PE12-R00, LXK2-PE12-S00, LXK2-PE14-T00, LXK2-PE14-U00<br> +LXK2-PB12-K00, LXK2-PB12-L00, LXK2-PB12-M00, LXK2-PB14-N00, LXK2-PB14-P00, LXK2-PB14-Q00<br> +LXK2-PR12-L00, LXK2-PR12-M00, LXK2-PR14-Q00, LXK2-PR14-R00<br> +LXK2-PD12-Q00, LXK2-PD12-R00, LXK2-PD12-S00<br> +LXK2-PH12-R00, LXK2-PH12-S00<br> +LXK2-PL12-P00, LXK2-PL12-Q00, LXK2-PL12-R00 +<p> +Source: www.luxeon.com<p> + +<u>KINGBRIGHT:</U><p> +KA-3528ASYC<br> +Source: www.kingbright.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Smal Outline Transistor</b> + + + + + + + + +>NAME +>VALUE + + + + + + +<b>DPAC</b> + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +>NAME +>VALUE + + + + + + + +<b>800mA and 1A Low Dropout (LDO) Positive Regulator</b><p> +1.8V, 2.5V, 2.85V, 3.3V, 5V, and Adj + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. + + + + + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +>Name +>Value ++ +- + + +<H3>JST-2-PTH-KIT</h3> +2-Pin JST, through-hole connector<br> +<br> +<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + +Standard 2-pin 0.1" header. Use with <br> +- straight break away headers ( PRT-00116)<br> +- right angle break away headers (PRT-00553)<br> +- swiss pins (PRT-00743)<br> +- machine pins (PRT-00117)<br> +- female headers (PRT-00115)<br><br> + + Molex polarized connector foot print use with: PRT-08233 with associated crimp pins and housings.<br><br> + +2.54_SCREWTERM for use with PRT-10571.<br><br> + +3.5mm Screw Terminal footprints for PRT-08084<br><br> + +5mm Screw Terminal footprints for use with PRT-08433 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find anything that moves- switches, relays, buttons, potentiometers. Also, anything that goes on a board but isn't electrical in nature- screws, standoffs, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + +<b>Stand Off</b><p> +This is the mechanical footprint for a #4 phillips button head screw. Use the keepout ring to avoid running the screw head into surrounding components. SKU : PRT-00447 + + + + + + + + +<b>Stand Off</b><p> +This is the mechanical footprint for a #4 phillips button head screw. Use the keepout ring to avoid running the screw head into surrounding components. SKU : PRT-00447 + + + + + + + + + + + + + + + +<b>#4 Stand Off</b><p> +This is the mechanical footprint for a #4 phillips button head screw. Use the keepout ring to avoid running the screw head into surrounding components. SKU : PRT-00447 + + + + + + + + + + + + + + + + + + + +<b>Test Pins/Pads</b><p> +Cream on SMD OFF.<br> +new: Attribute TP_SIGNAL_NAME<br> +<author>Created by librarian@cadsoft.de</author> + + +<b>TEST PAD</b> + + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + + + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>TP_SIGNAL_NAME + + + + + + +<b>TEST PIN</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + +47uF Tantalum SMT<br> +CAP-08310- 10V 10% (EIA-3528) + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + +1/6W Thru-hole Resistor - *UNPROVEN* + + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>Name +>Value + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + +1/4W Resistor, 0.4" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +1/2W Resistor, 0.5" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +1W Resistor, 0.6" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +2W Resistor, 0.8" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +<h3>AXIAL-0.3-KIT</h3> + +Commonly used for 1/4W through-hole resistors. 0.3" pitch between holes.<br> +<br> + +<b>Warning:</b> This is the KIT version of the AXIAL-0.3 package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + + + + + + + + + +This is the "EZ" version of the standard .3" spaced resistor package.<br> +It has a reduced top mask to make it harder to install upside-down. + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>Resistor</b> +Basic schematic elements and footprints for 0603, 1206, and PTH resistors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source-1.0L-F11/eagle/floppyemu 1.1.1/gerbers.zip b/source-1.0L-F11/eagle/floppyemu 1.1.1/gerbers.zip new file mode 100755 index 0000000..840a7aa Binary files /dev/null and b/source-1.0L-F11/eagle/floppyemu 1.1.1/gerbers.zip differ diff --git a/source-1.0L-F11/eagle/floppyemu 1.1.1/parts-1.1.txt b/source-1.0L-F11/eagle/floppyemu 1.1.1/parts-1.1.txt new file mode 100755 index 0000000..37381e5 --- /dev/null +++ b/source-1.0L-F11/eagle/floppyemu 1.1.1/parts-1.1.txt @@ -0,0 +1,33 @@ +ICs: +XC9572XL, 44-pin TQFP package = http://search.digikey.com/us/en/products/XC9572XL-10VQG44C/122-1448-ND/966629?wt.z_cid=ref_octopart_dkc_buynow +ATMega1284P, 44-pin TQFP package = http://search.digikey.com/us/en/products/ATMEGA1284P-AU/ATMEGA1284P-AU-ND/1914519 +74LVC244A level converter, 20-pin SSOP package = http://search.digikey.com/us/en/products/74LVC244ADB,112/568-1582-5-ND/763186 +800mA 1117 3.3V regulator, SOT223 package = http://search.digikey.com/us/en/products/LD1117S33TR/497-1242-1-ND/586242 +20 MHz 8pF SMD crystal, NX5032 package = http://search.digikey.com/us/en/products/NX5032GA-20.000000MHZ-LN-CD-1/644-1039-1-ND/1128911 + +Connectors: +DB-19 connector, male solder type = http://www.iec-usa.com/cgi-bin/iec/fullpic?G2FS4qvh;DB19MS;41 +IDC20 connector = http://search.digikey.com/us/en/products/SBH11-PBPC-D10-ST-BK/S9172-ND/1990065 +AVR ISP connector (2x3 IDC) = http://search.digikey.com/us/en/products/75869-131LF/609-2845-ND/1302569 +8-pin male 0.1 inch header +2-pin male 0.1 inch header +8-pin female 0.1 inch header +2-pin female 0.1 inch header + +Passives: +10x 0.1uF capacitors, 0805 package +1x 33uF tantalum cap, 0805 package +2x 18pF caps, 0805 package +3x 220 ohm resistors, 0805 package +1x 10K ohm resistor, 0805 package + +Miscellaneous: +Nokia 5110 graphical LCD = https://www.sparkfun.com/products/10168 +2x LEDs, 0805 package = http://search.digikey.com/us/en/products/APT2012SGC/754-1131-1-ND/1747848 +4x B3FS tactile switch, SMD = http://search.digikey.com/scripts/dksearch/dksus.dll?pname&WT.z_cid=ref_octopart_dkc_buynow&site=us&lang=en&name=SW1141-ND +TE 2041021-4 SD card holder = http://search.digikey.com/us/en/products/2041021-4/A101492CT-ND/2571152 + +Tools: +AVRISP mkII AVR programmer (or equivalent) = http://www.digikey.com/product-detail/en/ATAVRISP2/ATAVRISP2-ND/898891?WT.mc_id=PLA_898891&gclid=CO_xwcjWnbQCFYp_QgodXX0AUQ +SD or SDHC card + diff --git a/source-1.0L-F11/firmware/femu.bin b/source-1.0L-F11/firmware/femu.bin new file mode 100755 index 0000000..7980912 Binary files /dev/null and b/source-1.0L-F11/firmware/femu.bin differ diff --git a/source-1.0L-F11/firmware/firmware.xvf b/source-1.0L-F11/firmware/firmware.xvf new file mode 100755 index 0000000..443eb73 Binary files /dev/null and b/source-1.0L-F11/firmware/firmware.xvf differ diff --git a/source-1.0L-F11/firmware/floppyemu.hex b/source-1.0L-F11/firmware/floppyemu.hex new file mode 100755 index 0000000..3bbc610 --- /dev/null +++ b/source-1.0L-F11/firmware/floppyemu.hex @@ -0,0 +1,1983 @@ +:10000000B2C30000DFC30000DDC30000DBC300009B +:100010000C941F0ED7C300000C94AB0A0C94F70984 +:10002000D1C30000CFC30000CDC30000CBC300008C +:10003000C9C30000C7C30000C5C30000C3C300009C +:10004000C1C30000BFC300000C945A1DBBC3000015 +:10005000B9C30000B7C30000B5C30000B3C30000BC +:10006000B1C30000AFC30000ADC30000ABC30000CC +:10007000A9C30000A7C30000A5C30000A3C30000DC +:10008000A1C300009FC300009DC3000000000C003E +:100090001800240030003C004800540060006C0050 +:1000A0007800840090009C00A800B400C000CB0041 +:1000B000D600E100EC00F70002010D011801230158 +:1000C0002E01390144014F015A01650170017A0185 +:1000D00084018E019801A201AC01B601C001CA01E0 +:1000E000D401DE01E801F201FC010602100219024E +:1000F00022022B0234023D0246024F0258026102E4 +:100100006A0273027C0285028E029702A002A80294 +:10011000B002B802C002C802D002D802E002E8026F +:10012000F002F80200030803100318030C0C0C0C77 +:100130000C0C0C0C0C0C0C0C0C0C0C0C0B0B0B0B03 +:100140000B0B0B0B0B0B0B0B0B0B0B0B0A0A0A0A03 +:100150000A0A0A0A0A0A0A0A0A0A0A0A0909090903 +:100160000909090909090909090909090808080803 +:1001700008080808080808080808080896979A9BBD +:100180009D9E9FA6A7ABACADAEAFB2B3B4B5B6B7AC +:10019000B9BABBBCBDBEBFCBCDCECFD3D6D7D9DAD3 +:1001A000DBDCDDDEDFE5E6E7E9EAEBECEDEEEFF2E6 +:1001B000F3F4F5F6F7F9FAFBFCFDFEFF0001FFFF93 +:1001C0000203FF040506FFFFFFFFFFFF0708FFFF15 +:1001D000FF090A0B0C0DFFFF0E0F10111213FF1475 +:1001E00015161718191AFFFFFFFFFFFFFFFFFFFF8C +:1001F000FF1BFF1C1D1EFFFFFF1FFFFF2021FF2213 +:10020000232425262728FFFFFFFFFF292A2BFF2C69 +:100210002D2E2F303132FFFF333435363738FF394A +:100220003A3B3C3D3E3F0000211042206330844079 +:10023000A550C660E770088129914AA16BB18CC1B5 +:10024000ADD1CEE1EFF13112100273325222B5522C +:100250009442F772D662399318837BB35AA3BDD305 +:100260009CC3FFF3DEE36224433420040114E664FC +:10027000C774A44485546AA54BB528850995EEE555 +:10028000CFF5ACC58DD55336722611163006D7760C +:10029000F6669556B4465BB77AA719973887DFF7A5 +:1002A000FEE79DD7BCC7C448E5588668A7784008D4 +:1002B000611802282338CCC9EDD98EE9AFF94889F5 +:1002C00069990AA92BB9F55AD44AB77A966A711A6C +:1002D000500A333A122AFDDBDCCBBFFB9EEB799B45 +:1002E000588B3BBB1AABA66C877CE44CC55C222CBC +:1002F000033C600C411CAEED8FFDECCDCDDD2AAD95 +:100300000BBD688D499D977EB66ED55EF44E133E4B +:10031000322E511E700E9FFFBEEFDDDFFCCF1BBFE4 +:100320003AAF599F788F8891A981CAB1EBA10CD1BE +:100330002DC14EF16FE18010A100C230E3200450C6 +:10034000254046706760B9839893FBA3DAB33DC339 +:100350001CD37FE35EF3B1029012F322D232354216 +:10036000145277625672EAB5CBA5A89589856EF5C9 +:100370004FE52CD50DC5E234C324A0148104667466 +:10038000476424540544DBA7FAB79987B8975FE719 +:100390007EF71DC73CD7D326F2369106B0165766B6 +:1003A0007676154634564CD96DC90EF92FE9C899A1 +:1003B000E9898AB9ABA94458654806782768C01806 +:1003C000E1088238A3287DCB5CDB3FEB1EFBF98B79 +:1003D000D89BBBAB9ABB754A545A376A167AF10A56 +:1003E000D01AB32A923A2EFD0FED6CDD4DCDAABD89 +:1003F0008BADE89DC98D267C076C645C454CA23CA6 +:10040000832CE01CC10C1FEF3EFF5DCF7CDF9BAF58 +:10041000BABFD98FF89F176E367E554E745E932EF5 +:10042000B23ED10EF01E20202020202020202020AF +:100430002020202020202020202020002049646C23 +:1004400065002052656164005772697465005472DA +:1004500061636B202020205369646500313434309F +:100460004B204469736B436F707920696D616765D8 +:10047000003830304B204469736B436F70792069CA +:100480006D616765003430304B204469736B436F96 +:10049000707920696D61676500313434304B2072AA +:1004A000617720696D616765003830304B2072617B +:1004B0007720696D616765003430304B2072617759 +:1004C00020696D61676500696D616765206E6F7495 +:1004D00020636F6E746967756F7573006572726FF4 +:1004E00072206F70656E696E6720696D6167650067 +:1004F000505245563A2043616E63656C004E455834 +:10050000543A204C6F6164206669726D7761726540 +:1005100000626567696E0052656C65617365206293 +:100520007574746F6E7320746F0043504C44204692 +:1005300049524D574152452055504441544500437E +:100540006F6E74726173743A200053454C45435486 +:100550003A2053617665004E4558543A2044617202 +:100560006B657200505245563A204C696768746555 +:100570007200626567696E0052656C656173652023 +:10058000627574746F6E7320746F00434F4E5452D3 +:100590004153542041444A5553544D454E54004113 +:1005A00070702056657273696F6E20312E30204C4A +:1005B000002020202020464C4F50505920454D55BA +:1005C00020202020202000507265737320616E79F6 +:1005D00020627574746F6E006669726D7761726502 +:1005E0002E78766600436F756C64206E6F74206F92 +:1005F00070656E005570646174696E67206669721B +:100600006D776172652E2E2E00464154414C204577 +:1006100052524F52202020202020202020200057FE +:1006200052495445204552524F522020202020202C +:1006300020202020000000000017000300031F0AF4 +:100640001F0A1F050904120F171C000303000E11D7 +:10065000110E00050205040E041008000404040035 +:1006600010001804031E110F021F00191512151592 +:100670000A07041F1715091E151D1905031A150B66 +:1006800017150F000A00040C04040E1F0A0A0A1FA3 +:100690000E040115030E15161E051E1F150A0E1158 +:1006A000111F110E1F15151F05050E151D1F041F07 +:1006B000111F1108100F1F041B1F10101F061F1FF2 +:1006C0000E1F0E110E1F05020E191E1F0D161215FC +:1006D00009011F010F101F0718071F0C1F1B041B08 +:1006E000031C031915131F101002040810101F0417 +:1006F00006041010100003031A161C1F120C0C1213 +:10070000120C121F0C1A16041E050C2A1E1F021CA6 +:10071000001D0010201D1F0C12111F101E0E1E1E8A +:10072000021C0C120C3E120C0C123E1C0202141E77 +:100730000A021F120E101E0E180E1E1C1E120C1284 +:1007400006281E1A1F16041B11001F00111B040887 +:100750000C047C3C3E5E2B3D3F2F5B5D3B2C2A22F4 +:100760005C00451D491D11241FBECFEFD0E4DEBF44 +:10077000CDBF13E0A0E0B1E0EAE9F9E700E00BBF8C +:1007800002C007900D92A831B107D9F717E3A8E18D +:10079000B3E001C01D92AD3DB107E1F717E000E005 +:1007A000C4E6D7E040E006C022974109FE014BBFF6 +:1007B0000E947A39C236D1074007B1F70E94191852 +:1007C0000C94BC3C1DCC2F923F924F925F926F9243 +:1007D0007F928F929F92AF92BF92CF92DF92EF92D1 +:1007E000FF920F931F93DF93CF93CDB7DEB72D9773 +:1007F0000FB6F894DEBF0FBECDBF8B014A013E019C +:100800000894611C711CD301E4E2F1E02DE0019039 +:100810000D922150E1F7BB244424AA2452E8552E1E +:1008200042E2E42EF12CE80EF91E3EE0C32ED12C5C +:10083000CC0EDD1E22E8222E312C280C391CC701DB +:10084000B80140E250E00E94C92480329105A1F431 +:10085000D8011B968C911B9790E09C012F733070F0 +:100860002F30310559F183FD23C0F8018081853E89 +:1008700019F1882309F05AC0D4011C9280E02D960A +:100880000FB6F894DEBF0FBECDBFCF91DF911F91A1 +:100890000F91FF90EF90DF90CF90BF90AF909F901F +:1008A0008F907F906F905F904F903F902F90089522 +:1008B000F8018081882301F3BB24C1CFBB2021F53F +:1008C0008C91982F907E903409F0B9CF9FE1A92E9A +:1008D000A8221D964C90F1011082A5E7B0E085E7B3 +:1008E000582EF301AD01480D591D81919801280F33 +:1008F000311DD9018C91DA018D93AD01EC15FD0507 +:10090000A1F7BB24B3949BCFD8018C91AA948A15EC +:1009100099F61D968C911D97841571F6552009F452 +:100920008ECFB3EF5B0EA52DB0E0DBCF8E3221F280 +:10093000BB2081F031962BE090E001C08191392FEE +:100940003795332737959695932B980F2150B1F70C +:10095000941531F0C801B4010E94092481E08FCFC1 +:10096000FA2DF130B9F7452D50E043385105B4F771 +:100970009A0160E080E090E0880D991D280D391DF6 +:10098000D9012C91FC0120836F5F862F90E09C01A0 +:10099000240F351F233831057CF381E070CFEF92AF +:1009A000FF920F931F93DF93CF93CDB7DEB7A99735 +:1009B0000FB6F894DEBF0FBECDBFFC01DB018C91FA +:1009C0008E32A9F1838590E0887190708031910515 +:1009D00009F466C0009759F5848D958DA68DB78D65 +:1009E000803020E4920726E0A20720E0B20709F455 +:1009F00059C0803020E892072CE0A20720E0B2071F +:100A000009F454C0803020E8920726E1A20720E0D4 +:100A1000B20709F449C081509044A640B0408F3FCE +:100A20002FE2920721E1A20720E0B20778F020E050 +:100A3000822FA9960FB6F894DEBF0FBECDBFCF911F +:100A4000DF911F910F91FF90EF900895CF017E01EC +:100A50000894E11CF11CB7010E9409241E86198A22 +:100A60008E01025F1F4FC801B70141E00E94342A86 +:100A7000882371F0C80165E773E340E052E00E940B +:100A8000C924C8010E9433278091C733813081F087 +:100A90008989882361F2C8010E94332720E0C8CFEA +:100AA00021E0C6CF23E0C4CF25E0C2CF24E0C0CFF1 +:100AB0008091C833882361F78091B63390E0A0E03D +:100AC000B0E0BA2FA92F982F88272091B733820F33 +:100AD000911DA11DB11DB695A79597958795B695C2 +:100AE000A79597958795803921E0920720E0A20786 +:100AF00020E0B207F1F0803223E0920720E0A20765 +:100B000020E0B207A1F0803A25E0920720E0A2079A +:100B100020E0B20709F0BCCF28E08989882309F4D6 +:100B200087CFC80129A70E94332729A581CF27E0B5 +:100B3000F4CF26E0F2CF2F923F924F925F926F92C6 +:100B40007F928F929F92AF92BF92CF92DF92EF925D +:100B5000FF920F931F93DF93CF93CDB7DEB7C05FA4 +:100B6000D0400FB6F894DEBF0FBECDBF7C0110920F +:100B7000190310921803829640E050E0BA010E94D7 +:100B80004B2603E4C02ED12CCC0EDD1E13E6A12E85 +:100B9000B12CAC0EBD1EB4E26B2E712CC701B60198 +:100BA000A50111DE8823E1F18091180390911903CA +:100BB00021E08734920708F0A7C1C601B501EFDE36 +:100BC000882E882359F38091180390911903869DEC +:100BD0008001879D100D969D100D11240B581C4F00 +:100BE000C801B50146E150E00E94B339B8016A5E20 +:100BF0007F4FC6010E940924809118039091190328 +:100C0000869DF001879DF00D969DF00D1124EB5807 +:100C1000FC4F83A201969093190380931803BECFD3 +:100C20002091180330911903C751DF4F398328836E +:100C3000C95ED040F70185A182508230A8F184E2DC +:100C400090E0C751DF4FE881F981C95ED040E89F4D +:100C50008001E99F100DF89F100D11240B581C4FB7 +:100C6000C80160E071E046E150E00E94B339C8017C +:100C7000469660E071E04DE050E00E94B33982E0BA +:100C8000F80183A3C751DF4F28813981C95ED04065 +:100C90002F5F3F4FC751DF4F39832883C95ED04054 +:100CA0003093190320931803A8E92A2EA3E03A2EC3 +:100CB00080E090E07E010894E11CF11CF7E1CF2E6A +:100CC000D12CCC0EDD1EC751DF4FE881F981C95E02 +:100CD000D0408E179F0708F01EC1FC013196C3510A +:100CE000DF4FF983E883CD5ED040C751DF4F2881C5 +:100CF0003981C95ED040E217F30708F026C1C1016F +:100D00008397F101B496C151DF4FF983E883CF5E39 +:100D1000D0405F01C351DF4F48805980CD5ED04045 +:100D2000CA51DF4F8883C65ED04091012D503040BC +:100D3000C551DF4F39832883CB5ED040C951DF4F87 +:100D400039822882C75ED040392EC701CA51DF4F91 +:100D50006881C65ED040732D46E150E00E94B339F1 +:100D600088240AC00E0D1F1DF801808190E00E94AA +:100D70007E39F80180838394F70101900020E9F720 +:100D80003197EE19FF09082D10E00E171F0750F3D9 +:100D9000EDED8E2EEFEF9E2E8A0C9B1C682C292CDD +:100DA000C601B40146E150E00E94B33977240AC07D +:100DB0000C0D1D1DF801808190E00E947E39F80124 +:100DC00080837394F60101900020E9F73197EC19C4 +:100DD000FD09072D10E00E171F0750F3C701B601DC +:100DE00046E150E00E94A539282F392FC951DF4F25 +:100DF000E881F981C75ED04080818150823008F45B +:100E000080C0F50180818150823008F477C01216CD +:100E100013060CF055C0CE018D96CA51DF4F688184 +:100E2000C65ED040732D46E150E00E94B339CA51EE +:100E3000DF4F8881C65ED040932D662D722D46E12E +:100E400050E00E94B339862D922DBE01635D7F4F25 +:100E500046E150E00E94B339CE018D96C551DF4F77 +:100E600068817981CB5ED0404DE050E00E94B3397B +:100E700084010A5E1F4FC551DF4F88819981CB5E87 +:100E8000D040B8014DE050E00E94B339C801BE0126 +:100E9000635D7F4F4DE050E00E94B339C951DF4F91 +:100EA000E881F981C75ED0408081F5019081C95108 +:100EB000DF4FE881F981C75ED0409083F5018083E0 +:100EC0000894411C511C24E230E0A20EB31EC7510D +:100ED000DF4F88819981C95ED0404816590608F4D1 +:100EE00034CFC151DF4F28803980CF5ED040C3510D +:100EF000DF4F88819981CD5ED040E5CE28513C4FAF +:100F000086CF285E33407DCFC751DF4F99838883DA +:100F1000C95ED0408FCEC051DF4F0FB6F894DEBF10 +:100F20000FBECDBFCF91DF911F910F91FF90EF903A +:100F3000DF90CF90BF90AF909F908F907F906F90F9 +:100F40005F904F903F902F900895C1018496C151BA +:100F5000DF4F99838883CF5ED040C3CF8F929F921B +:100F6000AF92BF92CF92DF92EF92FF920F931F93B7 +:100F7000CF93DF9380911A0390911B0320911C0360 +:100F800030911D032817390728F430931B03209351 +:100F90001A03C90104968217930730F42450304095 +:100FA00030931B0320931A0380E060E00E949A1D97 +:100FB00081E06FE70E948B1DC3E1D0E081E060E437 +:100FC0000E948B1D2197D1F783E091E00E948F1E34 +:100FD000C3E1D0E081E060E40E948B1D2197D1F74E +:100FE00081E06FE70E948B1D209118033091190357 +:100FF0002115310509F464C140911A0350911B0376 +:10100000CA0105964817590708F033C1421753071C +:1010100008F02FC164E270E0469F7001479FF00C1A +:10102000569FF00C112488E993E0E80EF91EEA01BE +:1010300091E0C92ED12CBB24B39480911C039091D4 +:101040001D03C817D90709F0BB24AC2C80E06C2D18 +:101050000E949A1D04E510E007C060E081E00E9454 +:101060008B1D0150104049F0BB20B9F36FE781E0C0 +:101070000E948B1D01501040B9F781E06A2D0E943B +:101080009A1D870103521040902E812EC8016B2DAE +:1010900043E50E94A61DF70180818150823008F44B +:1010A000BDC0BB2009F0A4C08601219640911A035F +:1010B00050911B03CA010596C817D907E0F120918A +:1010C0001803309119032630310508F047C0EE248B +:1010D000E39482E56E2D0E949A1D81E060E00E94FB +:1010E0008B1D81E060E00E948B1DE3947E2D7630A5 +:1010F00081F780911A0390911B039801280F391FE3 +:1011000040911C0350911D034217530708F4E2C09D +:101110002150304030931D0320931C0304301105EF +:1011200009F02CCF009709F429CF019790931B0366 +:1011300080931A0323CF2091180330911903089448 +:10114000C11CD11C64E270E0E60EF71EC217D30783 +:1011500008F471CF2630310508F4B9CFE7E2F0E0AA +:101160004E9FC0014F9F900D5E9F900D11248D5397 +:101170009F4FB9010E94293988E0E82EE60E83ECE2 +:1011800090E0B9010E942939CE2CC61AC8E0D0E0FF +:10119000BB24B39482E56B2D0E949A1D81E060E030 +:1011A0000E948B1D4C2F9E01295F3F4F2C173D073E +:1011B0000CF484C060E00AC0E41650F066956068E4 +:1011C0004F5F842F90E0281739074CF04C15A0F79B +:1011D00066954F5F842F90E028173907BCF781E0B0 +:1011E0000E948B1DB39428967B2D763099F681CF83 +:1011F00084E393E0692D782D46E150E00E94B339F5 +:10120000B8016A5E7F4F8EE193E04DE050E00E94AE +:10121000B339F701808180934A0346CF89E46A2D70 +:101220000E949A1DBB2041F181E06FE70E948B1D57 +:1012300081E063E40E948B1D81E06DE50E948B1DBF +:1012400081E06DE50E948B1D81E06DE50E948B1DA4 +:1012500081E06BE50E948B1D81E06BE50E948B1D98 +:1012600081E063E40E948B1D6FE781E00E948B1D8B +:1012700018CF00E010E027CF81E060E00E948B1DD6 +:1012800081E06CE30E948B1D81E062E20E948B1D75 +:1012900081E062E20E948B1D81E062E20E948B1D70 +:1012A00081E064E20E948B1D81E064E20E948B1D5C +:1012B00081E06CE30E948B1D60E0D7CF60E08FCFB0 +:1012C00080E061E00E949A1D8FE091E060E044E5DB +:1012D0000E94A61DDF91CF911F910F91FF90EF907B +:1012E000DF90CF90BF90AF909F908F900895813006 +:1012F000910559F0009721F48091A135882309F4D4 +:1013000008958EE995E30C94332710929E35109240 +:10131000A13508958FE781B9559A209A3A9A3D9A56 +:101320003E9A3B9A239A5C9A599A5A9A5F9A5B9A88 +:10133000179A589A409A419A289A429A45984698FC +:10134000439A2B9AE3E7F0E0808181608083EDE6A9 +:10135000F0E0808182608083808181608083089555 +:101360001F93DF93CF93CDB7DEB72A970FB6F894CC +:10137000DEBF0FBECDBFCE010196DC01EEEDF2E087 +:101380002AE001900D922150E1F7E0914C03F0E04A +:10139000F595E795F595E795F595E795F595E79535 +:1013A0001FB7F894E53008F0E4E0F0E0EE0FFF1F1F +:1013B000E80FF91F20813181220F331F40E050E0F8 +:1013C00060E07DE281E391E00E945F3930935B034E +:1013D00020935A031FBF82E086BB2A960FB6F8946B +:1013E000DEBF0FBECDBFCF91DF911F9108951F9239 +:1013F0000F920FB60F920BB60F9211242F933F93BB +:101400004F935F936F937F938F939F93AF93BF930C +:10141000CF93DF93EF93FF93489B2FC0E0914C0352 +:1014200080915503882309F03DC0F0E0E45DFE4F54 +:10143000249130E0220F331F21153105A9F537998A +:101440005DC080914C038F5F80934C0380914C036F +:10145000882309F064C04598429A4899FECF429883 +:10146000459A7EDFC0919435D0919535C330D10532 +:1014700008F057C081E080935103FF91EF91DF9115 +:10148000CF91BF91AF919F918F917F916F915F911C +:101490004F913F912F910F900BBE0F900FBE0F9069 +:1014A0001F90189524E230E080E090E040E050E0AA +:1014B00068E188589A4CFC01808180FF03C0683144 +:1014C00059F1542F4F5F842F90E0821793070CF14E +:1014D000561708F4B4CF862FE82FF0E0E858FA4CFE +:1014E000908191FF03C0908191609083908194607E +:1014F00090838F5F581780F7379BA3CF80914C0361 +:10150000882309F4A3CF80914C03815080934C032E +:101510009DCF4831E9F2CDCF542F642FD3CF459AD8 +:101520009BCF8FE593E061E371E046E150E00E94DC +:10153000B339C851DC4FD0937735C09376351092CC +:10154000500381E0809351038093520310929535AC +:10155000109294358FCF1F920F920FB60F920BB649 +:101560000F9211241F932F933F934F935F936F9389 +:101570007F938F939F93AF93BF93CF93DF93EF931B +:10158000FF9386B190E095958795817090914E0379 +:10159000891791F090915803923009F46DC0109220 +:1015A0004E0311E010935103C0919435D0919535BD +:1015B000C330D10508F047C086B1817011E08127A2 +:1015C000909150038917C9F0809350038091500384 +:1015D000882349F58FE781B9469880916B008F7712 +:1015E00080936B00C0919435D0919535C330D1056F +:1015F00008F045C081E080935103FF91EF91DF91A6 +:10160000CF91BF91AF919F918F917F916F915F919A +:101610004F913F912F911F910F900BBE0F900FBED6 +:101620000F901F90189511B8469A80916B008068B2 +:1016300080936B0080B180788093933510929535BC +:1016400010929435D7CF8FE593E061E371E046E1E6 +:1016500050E00E94B339C053D84FD0937735C09330 +:101660007635109250031093510310935203109249 +:10167000953510929435A0CF80934E0392CF8FE58D +:1016800093E061E371E046E150E00E94B339C85451 +:10169000D44FD0937735C093763510925003109382 +:1016A0005103109352031092953510929435A2CFA6 +:1016B0001F93E0B1E0688091943590919535843026 +:1016C000910588F48330910509F487C0DC01A153AA +:1016D000BD4F2C912E1709F404C11092953510922C +:1016E00094351F910895F0E0EA5DFE4FE49132E0F9 +:1016F0008F3B930748F59C012370307022303105F1 +:1017000009F4BBC02330310509F449C1213031054A +:1017100009F418C1EE0FEE0FE093963540919A351B +:1017200050E09A01220F232F221F330B20939B3569 +:10173000440F551F422B40939A350196909395354F +:10174000809394351F910895F2E08F3B9F0709F431 +:10175000C1C022E0803C920709F4CEC032E0813C57 +:10176000930709F4E2C1F2E0823C9F0709F0B5CF8C +:1017700080919635982F990F990F90939635E82B75 +:1017800090919A35E917C9F08FE593E062E971E02D +:1017900046E150E00E94B33980E490E090937735C1 +:1017A000809376351092500381E0809351038093AB +:1017B00052031092953510929435E0919735F0E0F0 +:1017C000E858FA4C808182608083808181608083C8 +:1017D00080818B7F80832B9A80CFF0E0EA5DFE4F83 +:1017E0001491E0914C0380915503882309F082C045 +:1017F000F0E0E45DFE4FE4911E1708F04DC1E0916A +:101800004C03882309F074C0F0E0E45DFE4FE491DE +:1018100080914E03E89F802D1124810F809397358E +:1018200090E0DC01A858BA4C2C9122FDE0C0982F22 +:101830008827990F8B589C4F90939D3580939C35AA +:101840008C9184608C938C918D7F8C9380914C03D0 +:101850008093903580914E0380939135109392350B +:101860002B9810929A351092993510929835809154 +:10187000943590919535019661CF50919635452FCD +:10188000407C4E2B2091983542278431910578F089 +:10189000E0919C35F0919D354193F0939D35E09317 +:1018A0009C35509196358091943590919535609105 +:1018B0009B352091993530E0260F311D240F311DC5 +:1018C0002093993530939B35550F550F509396358E +:1018D000019634CFEE0FEE0FE093963580EC92E058 +:1018E0002DCF20915403222309F0F7CE019626CF65 +:1018F000E2E18ECFE2E180CF80919635982F990F6B +:10190000990F90939635807C8E2B909198358917FE +:1019100009F46AC08FE593E06CE671E046E150E0BF +:101920000E94B3398EE390E09093773580937635BB +:101930001092500381E0809351038093520381E021 +:1019400090E0FCCE50919635452F407C4E2B209157 +:101950009A3542278431910578F0E0919C35F091D9 +:101960009D354193F0939D35E0939C35509196358C +:10197000809194359091953560919B352091983563 +:1019800030E0260F311D240F311D20939835309300 +:101990009B35550F550F509396350196CFCE4091FC +:1019A00096354E2B2091993542278431910568F068 +:1019B000E0919C35F0919D354193F0939D35E093F6 +:1019C0009C35809194359091953550919B3520911F +:1019D0009A3530E0250F311D240F311D20939A35A3 +:1019E00030939B350196AACE81EC92E0A7CE309140 +:1019F0004C0320914E038DB79EB70C970FB6F89409 +:101A00009EBF0FBE8DBFADB7BEB711968FE593E0F9 +:101A1000EDB7FEB79283818386E190E013969C93A5 +:101A20008E93129788E591E015969C938E93149768 +:101A300016963C93169717961C92179718962C9308 +:101A4000189719961C9219971A961C931A971B9619 +:101A50001C920E94C2398DE390E090937735809379 +:101A600076351092500381E08093510380935203A6 +:101A700010929535109294358091973590E02DB75E +:101A80003EB7245F3F4F0FB6F8943EBF0FBE2DBF49 +:101A9000DC01A858BA4CCBCE20914C038DB79EB731 +:101AA0000A970FB6F8949EBF0FBE8DBFADB7BEB7F5 +:101AB00011968FE593E0EDB7FEB79283818386E1BF +:101AC00090E013969C938E93129782E491E0159682 +:101AD0009C938E93149716961C93169717961C92A8 +:101AE000179718962C93189719961C920E94C23932 +:101AF0008CE390E090937735809376351092500385 +:101B000081E0809351038093520310929535109297 +:101B10009435809155032DB73EB7265F3F4F0FB6E2 +:101B2000F8943EBF0FBE2DBF6ACE80919635982F98 +:101B3000990F990F90939635807C8E2B90919935C3 +:101B4000891759F08FE593E06FE771E046E150E0C7 +:101B50000E94B3398FE390E0E7CE82EC92E0EECDC5 +:101B60004091560350915703E2EEF2E025913491F3 +:101B700060E07FEF2627372791EA692F632770E01F +:101B8000660F771F6A5D7D4FFB0165917491322F5F +:101B90002227262737279327E92FF0E0EE0FFF1F94 +:101BA000EA5DFD4F65917491322F22272627372752 +:101BB000EBEFE327F0E0EE0FFF1FEA5DFD4F6591CD +:101BC0007491322F222726273727B82FBB0FA0E08A +:101BD000AB58BC4F80E090E0722F6627ED91E32771 +:101BE000F0E0EE0FFF1FEA5DFD4F259134912627AF +:101BF0003727019662E08030960771F730935703DC +:101C00002093560342175307C9F08FE593E065EA26 +:101C100071E046E150E00E94B33986E490E0909391 +:101C20007735809376351092500381E0809351038D +:101C300080935203109295351092943508951F9217 +:101C40000F920FB60F920BB60F9211242F933F9362 +:101C50004F935F936F937F938F939F93AF93BF93B4 +:101C6000EF93FF9390B180915003882309F456C0FD +:101C7000892F807890919335891709F44FC080930C +:101C8000933590915503992309F46FC0882309F483 +:101C900061C020B12F7080919635282B2093963506 +:101CA00080919435909195358230910509F45FC00B +:101CB000009709F446C08130910509F46DC032E007 +:101CC0008330930708F458C0A2E083309A0709F4E0 +:101CD0009AC0B2E084309B0709F530E0809156034A +:101CE00090915703822B932B909357038093560325 +:101CF0008091973535DFE0919735F0E0E858FA4C60 +:101D000080818260808380818160808380818B7FFD +:101D100080832B9A1092953510929435FF91EF9114 +:101D2000BF91AF919F918F917F916F915F914F91F3 +:101D30003F912F910F900BBE0F900FBE0F901F90F1 +:101D40001895213A59F781E090E09093953580936A +:101D50009435E4CF80B190E082959295907F98275A +:101D6000807F982780939635D9CFA2DCD7CF2B3FA1 +:101D7000E9F0213A79F6D2CF30919735F32FFF0F62 +:101D8000E0E0E80FF91FEE58FC4F20830196909396 +:101D9000953580939435C2CF213A09F0BBCF82E0CC +:101DA00090E09093953580939435B8CF83E090E0A0 +:101DB00090939535809394352091590320939735CE +:101DC000822F90E0FC01E858FA4C308132FD26C0A9 +:101DD000982F8827990F8B589C4F90939D3580930F +:101DE0009C3580818460808380818D7F8083809119 +:101DF0004C038093903580914E03809391352093CE +:101E000092352B988BCF109256032093570384E082 +:101E100092E0909395358093943580CF50914C0308 +:101E200040914E032DB73EB72C5030400FB6F8947A +:101E30003EBF0FBE2DBFEDB7FEB731962FE533E0A5 +:101E4000ADB7BEB712963C932E93119726E130E0C2 +:101E50003383228328E531E0358324835683178238 +:101E600040871186938782870E94C23987E490E079 +:101E700090937735809376351092500381E080936C +:101E800051038093520310929535109294352DB7DB +:101E90003EB7245F3F4F0FB6F8943EBF0FBE2DBF35 +:101EA0003DCFF89490915003992341F48F7782B9F4 +:101EB000459A079BFECF0799FECF459878940895E1 +:101EC0008AE082B9459A079BFECF0799FECF4598D5 +:101ED000E091570381EAE827F0E0EE0FFF1FEA5D8B +:101EE000FD4F859194913091560320E082279327EE +:101EF000909357038093560381E182B9459A079BDB +:101F0000FECF0799FECF45980895982F92959F7020 +:101F100092B9459A079BFECF0799FECF4598482F67 +:101F20004F70E0915703E827F0E0EE0FFF1FEA5DE6 +:101F3000FD4F859194913091560320E0822793279D +:101F4000909357038093560342B9459A079BFECF5F +:101F50000799FECF459808952F923F924F925F9236 +:101F60006F927F928F929F92AF92BF92CF92DF92A9 +:101F7000EF92FF920F931F93DF93CF9300D00F92B6 +:101F8000CDB7DEB78983692EA2EDCA2EA2E0DA2E84 +:101F9000992422243324EE24FF2400E010E088C09A +:101FA0001070C801880F991F2801440C452C441C4F +:101FB00055085194482A592AF6010191852D9927EF +:101FC000820D931D800F911DAFEF4A225524D6013B +:101FD0001196AC906F010894C11CD11CA7014A0D49 +:101FE000511D9C0120703170232F3327420F531F46 +:101FF0003FEF232E312C2822392271802FEFE22E41 +:10200000F12CE422F522872C8E24042510E0A22452 +:10201000BB24F501E07CF070F595E795F595E79523 +:10202000F595E795F595E7959801207C3070359505 +:10203000279535952795E22BF32B882D829586954C +:102040008695837090E0E82BF92BE458FE4F84913D +:102050004A835B8326DF0F73107004581E4FF8010C +:1020600084911FDF809151034A815B81882309F0AD +:10207000A9C00894C11CD11C8201070D111D40701C +:102080005170452F5527040F151FF501EF73F070A0 +:10209000E458FE4F849105DFE82DF0E0EF73F07017 +:1020A000E458FE4F8491FDDE9394F92DFE3A41F001 +:1020B000292D243009F074CF9981C92ED62C70CFE8 +:1020C0001070C801880F991F5801AA0CAB2CAA1CCC +:1020D000BB08B194A82AB92AD6010C91200E311C54 +:1020E0008B2D9927280E391E1196CC90EC0CF11CE3 +:1020F000C10180709170892F9927E80EF91E0A2579 +:1021000010E0C224DD24F601E07CF070F595E7953F +:10211000F595E795F595E795F595E795C801807CE8 +:1021200090709595879595958795E82BF92BE458B0 +:10213000FE4F8491B6DEF801EF73F070E458FE4F65 +:102140008491AFDEF601EF73F070E458FE4F849196 +:10215000A8DEF101E07CF070F695E795F695E7953D +:10216000C501807C90700024880F991F001C880F87 +:10217000991F001C892F902DE82BF92BC701807C1B +:102180009070929582958F7089279F708927E82B90 +:10219000F92BE458FE4F849184DEF101EF73F07067 +:1021A000E458FE4F84917DDEF701EF73F070E45840 +:1021B000FE4F849176DEF501EF73F070E458FE4F28 +:1021C00084916FDE0F900F900F90CF91DF911F9150 +:1021D0000F91FF90EF90DF90CF90BF90AF909F90C6 +:1021E0008F907F906F905F904F903F902F900895C9 +:1021F000CF93DF9380E060E00E949A1D81EB95E031 +:1022000061E00E94271E8FE995E00E948639819542 +:10221000880F865D62E00E949A1D8FE995E060E07C +:102220000E94271E4DB75EB7485050400FB6F89435 +:102230005EBF0FBE4DBFEDB7FEB73196CFE5D3E021 +:10224000ADB7BEB71296DC93CE93119786E190E0BE +:102250009383828383EB91E09583848380915E03F3 +:10226000868317820E94C239FE0101900020E9F79F +:102270003197EC1BFD0B4DB75EB7485F5F4F0FB654 +:10228000F8945EBF0FBE4DBF8E2F8195880F865D7F +:1022900063E00E949A1DCE0160E044E50E94A61D05 +:1022A0002B980E94531D95E028E04FEF53ED60E31B +:1022B000415050406040E1F700C0000085B18227E6 +:1022C00085B9915091F70E94571DDF91CF910895E4 +:1022D000CF92DF92EF92FF920F931F93DF93CF93F2 +:1022E00000D000D0CDB7DEB780E060E00E949A1D3C +:1022F0000E94D21E80E060E00E949A1D8BE895E06B +:1023000060E00E94271E80E062E00E949A1D88E73C +:1023100095E060E00E94271E80E063E00E949A1D25 +:1023200082E795E060E00E94271E499BFECF4A9B12 +:10233000FCCF4C9BFACF80E060E00E949A1D0E9487 +:10234000D21E80E062E00E949A1D84E695E060E083 +:102350000E94271E80E063E00E949A1D87E595E0B9 +:1023600060E00E94271E80E064E00E949A1D8AE4DB +:1023700095E060E00E94271E8E010F5F1F4F84ECE6 +:10238000E82E81E0F82EB4E0CB2ED12C16C080913F +:10239000C7358F3F29F08091C7358F5F8093C73550 +:1023A00080E061E20E948B1D6091C73580E00E9451 +:1023B0008B1D80E060E20E948B1D80E060E00E9447 +:1023C0009A1D8FE395E060E00E94271E8091C7353B +:1023D0002DB73EB7285030400FB6F8943EBF0FBE21 +:1023E0002DBFEDB7FEB73196ADB7BEB712961C93B1 +:1023F0000E931197D382C282F582E482868317827C +:102400000E94C2392DB73EB7285F3F4F0FB6F894F0 +:102410003EBF0FBE2DBFC80160E044E50E94A61D6F +:102420008FEF99E6A8E181509040A040E1F700C00D +:102430000000499B04C04A9B02C04C99FACF4A9BBA +:10244000A6CF49990BC08091C735813808F4A8CF31 +:102450008091C73581508093C735A2CF4C99A0CFCA +:102460006091C73581E090E00E940A3C0F900F9088 +:102470000F900F90CF91DF911F910F91FF90EF90F0 +:10248000DF90CF9008951F930E94D21E80E060E0FD +:102490000E949A1D84E393E060E044E50E94A61D3B +:1024A00080E061E00E949A1D8EE995E36EE173E0A1 +:1024B00043E00E94342A882309F48AC080914A03A9 +:1024C000833029F1863019F182E0809358038EE938 +:1024D00095E36BEB75E34FEB55E30E94562388239E +:1024E000D1F487EC94E060E00E94271E8FEF93E226 +:1024F000A4EF81509040A040E1F700C0000010E040 +:102500008EE995E30E943327812F1F91089581E082 +:1025100080935803DCCF80E061E00E949A1D809197 +:102520004A03853009F4BFC0863008F05FC08330AD +:1025300009F4A1C0843039F489EA94E060E00E9493 +:10254000271E80914A0391E0863008F490E0909332 +:1025500075354F998CC0992309F45CC081E0809354 +:10256000540348E754E060E070E08EE995E30E9490 +:102570004B268EE995E365E773E040E052E00E9468 +:10258000C924E0917503F0E0EA58FC4F10821092E4 +:102590008B0380E062E00E949A1D86E793E060E092 +:1025A00044E50E94A61D80E064E00E949A1D8EE42E +:1025B00094E060E00E94271E80915403882379F5FF +:1025C00011E08EE995E30E943327812F1F91089532 +:1025D0008EE995E36EE173E041E00E94342A88239E +:1025E00009F464C081E08093540371CF873009F40B +:1025F00052C0873008F447C0883009F0A4CF8CE57A +:1026000094E060E00E94271E81E080935503809152 +:102610004A0399CF44E254E060E070E0A6CF8DE435 +:1026200060E00E949A1D81E060E00E948B1D81E0C5 +:1026300068E70E948B1D81E06EE70E948B1D81E0A0 +:1026400069E70E948B1D81E069E70E948B1D81E094 +:102650006EE70E948B1D81E068E70E948B1D11E0F0 +:102660008EE995E30E943327812F1F91089581E021 +:102670008093540370CF88EB94E060E00E94271EA3 +:1026800080914A0360CF85E894E060E00E94271EB5 +:1026900080914A0358CF81E794E060E00E94271EB2 +:1026A00080914A0350CF89E994E0ABCF8CED94E060 +:1026B00060E00E94271E1ACF1F931FB7F894E09185 +:1026C0004C03F0E0EE0FFF1FE850F0418081809353 +:1026D0004C030E948A0910924C0310924D031092F1 +:1026E000510310924E0310924F0310925003109218 +:1026F000530382E0809358031092590310925403BD +:10270000109255031092520310925D0310925C03D5 +:102710001092773510927635109295351092943547 +:1027200080E090E0FC01E858FA4C10820196883174 +:102730009105C1F711B8469A28988FE798E3A1E070 +:1027400081509040A040E1F700C0000080B18F7739 +:1027500080935E0346988FE781B9289A8091640040 +:10276000877F8093640083E48093800089E1809375 +:1027700081000E94B0090E94DE1E0E94D21E1FBF6F +:102780001F910895FF920F931F93CF93DF938C01B6 +:10279000F0905203C0917635D09177358DDF0E944D +:1027A000D21E80E060E00E949A1DFF2009F43FC025 +:1027B0008FE196E061E00E94271E80E061E00E94C8 +:1027C0009A1DC80160E044E50E94A61D8DB79EB722 +:1027D00008970FB6F8949EBF0FBE8DBFEDB7FEB73A +:1027E00031960FE513E0ADB7BEB712961C930E936A +:1027F000119786E190E09383828387EC91E0958343 +:102800008483D783C6830E94C2398DB79EB708964A +:102810000FB6F8949EBF0FBE8DBF80E065E00E94AA +:102820009A1DC80160E044E50E94A61DFFCF89E023 +:1028300096E061E00E94271E80E061E00E949A1D00 +:10284000C80160E044E50E94A61DF0CF1F93CF931E +:10285000DF930E94D21E80E060E00E949A1D84EF08 +:1028600095E060E00E94271E4A9BFECF8FEF99E61D +:10287000A8E181509040A040E1F700C000008EE93F +:1028800095E36AEC71E041E00E94342A882331F537 +:1028900062E00E949A1D85EE95E060E00E94271E8E +:1028A00080E063E00E949A1D88ED95E060E00E9460 +:1028B000271E80E065E00E949A1D87EC95E060E0AD +:1028C0000E94271E499B04C04A9B02C04C99FACF24 +:1028D0000E94D21EDF91CF911F9108958EE995E35A +:1028E00065E773E040E052E00E94C92497FD4DC0C7 +:1028F0001092BA351092B93586E195E10E94C93837 +:102900001FB7F8940E947338EC011FBF8EE995E35E +:102910000E94332780E062E00E949A1D209761F1B7 +:10292000ADB7BEB718970FB6F894BEBF0FBEADBF18 +:10293000EDB7FEB731968FE593E012969C938E9398 +:10294000119786E190E09383828387EF91E09583EE +:102950008483D783C6830E94C2398DB79EB70896F9 +:102960000FB6F8949EBF0FBE8DBF8FE593E060E079 +:1029700044E50E94A61D9DCF8FE593E067EE71E0D0 +:1029800046E150E00E94B339F0CF87ED91E0FADEE6 +:10299000AFCF80E060E00E949A1D0E94D21E80E0CE +:1029A00060E00E949A1D8AE295E060E00E94271E86 +:1029B00080E062E00E949A1D87E195E060E00E945D +:1029C000271E80E063E00E949A1D81E195E060E0AF +:1029D0000E94271E499BFECF4A9BFCCF4C9BFACFFF +:1029E00080E062E00E949A1D8DEF94E060E00E941A +:1029F000271E80E063E00E949A1D80EF94E060E073 +:102A00000E94271E8FEF99E6A8E181509040A040D8 +:102A1000E1F700C00000499B04C04A9B02C04C99EA +:102A2000FACF4A9B02C00C94D21E10CF2091B93528 +:102A30003091BA3582E02030380759F0F901EB586F +:102A4000FC4F80812F5F3F4F3093BA352093B935CB +:102A500008958EE995E365E773E040E052E00E9457 +:102A6000C92497FD0BC01092BA351092B93585B1C3 +:102A700098E0892785B920E030E0E0CF87ED91E04C +:102A800081DEF1CF909155039923E1F4E82FF0E036 +:102A9000E45DFE4FE491F0E0262F30E02E173F0773 +:102AA000B4F4AF014F5F5F4F55954795E0FD14C0FB +:102AB00031972E173F0759F06417B0F0862F8F5FBC +:102AC000841B0895262F30E02131310514F080E079 +:102AD0000895862F8F5F0895E42FF0E031972E1729 +:102AE0003F0751F780E00895842F860F0895FF92E5 +:102AF0000F931F938C01F22E0E945520882379F1A9 +:102B0000C80165E773E30E94AD1F882391F1E9ECEA +:102B1000F3E3BF2DBB0FA0E0AB58BC4F81918D9369 +:102B200085E3E537F807D1F7C80165E773E30E944D +:102B3000AD1F882311F1E5E7F3E3BF2DBB0FA0E044 +:102B4000AF5DBA4F81918D9383E3E93CF807D1F7EC +:102B5000C8010E943D201F910F91FF90089588E0C9 +:102B600092E010DEC80165E773E30E94AD1F882381 +:102B700071F68CE192E006DECACF8CE192E002DED3 +:102B8000DACF2F923F924F925F927F928F929F92D5 +:102B9000AF92BF92CF92DF92EF92FF920F931F936B +:102BA000DF93CF93CDB7DEB760970FB6F894DEBF53 +:102BB0000FBECDBF982E792E862E80915503882387 +:102BC00009F4B7C004E210E062E1462E512C80E027 +:102BD00090E020E0FF2458E1E52E46E1A42EB12C40 +:102BE0003CE2C32E32E0D32E1801122F88589A4CA3 +:102BF000DC018C9180FF35C080919035881661F1A1 +:102C0000809190352DB73EB72A5030400FB6F894DA +:102C10003EBF0FBE2DBFEDB7FEB731962FE533E0B7 +:102C2000ADB7BEB712963C932E931197B382A28292 +:102C3000D582C48286821782808711860E94C2391B +:102C40004DB75EB7465F5F4F0FB6F8945EBF0FBEDD +:102C50004DBF8FE593E096DD5E2D583109F466C0D7 +:102C6000F12E1F5F812F90E0821593050CF45AC05E +:102C7000BE2DB83109F43EC080915403882361F41D +:102C800066C0EE2DF0E0E858FA4C80818E7F80839C +:102C900080818B7F8083E394FE1498F7EDB7FEB7B5 +:102CA00038970FB6F894FEBF0FBEEDBF31960FE513 +:102CB00013E0ADB7BEB712961C930E93119786E141 +:102CC00090E09383828381E492E09583848386827B +:102CD00017820E94C239EDB7FEB738960FB6F89446 +:102CE000FEBF0FBEEDBF80E065E024D7C80160E005 +:102CF00044E52CD760960FB6F894DEBF0FBECDBF6B +:102D0000CF91DF911F910F91FF90EF90DF90CF90C7 +:102D1000BF90AF909F908F907F905F904F903F902B +:102D20002F900895183109F4A3CF60CFF12EE12E32 +:102D300098CFE62FF0E0E45DFE4FE4914E2E55244F +:102D40008201000F111F01151105A1F240CFABD672 +:102D5000D6D66B877C878D879E87FE1408F461C169 +:102D6000482D50E05A8749871A01220C331CC101B3 +:102D7000880F991F880F991F880F991F820D931D27 +:102D80009C0140E050E029833A834B835C830E2D05 +:102D9000F101E457FF4F859194919C0140E050E090 +:102DA0002D833E834F8358871E2DAF2C42C08090C9 +:102DB00091352091580330E040E050E069817A81FC +:102DC0008B819C810E940A396B017C018091BB350B +:102DD0009091BC35A091BD35B091BE35C80ED91EBD +:102DE000EA1EFB1E282D30E0429EC001439E900D3E +:102DF000529E900D1124AA2797FDA095BA2FC80EB8 +:102E0000D91EEA1EFB1EC00ED11CE11CF11C2F8531 +:102E10003889322F2227330F2B583C4F892D972D7D +:102E2000B701A6010E947520882371F10F5FA016DB +:102E300088F1402F50E0588B4F87FA01E858FA4C40 +:102E4000808180FDF3CF80915503882309F0AFCFB7 +:102E5000C090BB35D090BC35E090BD35F090BE350C +:102E6000C00ED11CE11CF11C2091580330E040E061 +:102E700050E06D817E818F8198850E940A39C60E4F +:102E8000D71EE81EF91EC3CF86E592E07BDC0F5FFC +:102E9000A01678F6E12EFA2C80915503882309F0CC +:102EA0004FC0F101E457FF4F65917491A090BB357D +:102EB000B090BC35C090BD35D090BE35AE0CB11CC5 +:102EC000C11CD11C80E090E02091580330E040E02C +:102ED00050E00E940A39A60EB71EC81ED91E0F2D3B +:102EE00010E00F5F1F4F0E191109222717FD2095C3 +:102EF000322F892D972DB601A5010E94102288231B +:102F000059F487C0F801E858FA4C80818E7F80839D +:102F100080818B7F8083E394FE14D0F10E2D10E02E +:102F2000B801762F6627770F6B587C4F892D972D28 +:102F30000E949E21882331F789E792E023DCE2CFCB +:102F40008091913590E0489E5001499EB00C589E6A +:102F5000B00C1124CC24B7FCC094DC2C8091BB3580 +:102F60009091BC35A091BD35B091BE35A80EB91E6B +:102F7000CA1EDB1EAE0CB11CC11CD11CB101660FF8 +:102F8000771F660F771F660F771F620D731D9ACF2D +:102F9000892D972D0E945122882309F43EC089E192 +:102FA00080935D0384D5ABD5ADB7BEB71C970FB684 +:102FB000F894BEBF0FBEADBFEDB7FEB731960FE5BB +:102FC00013E012961C930E93119726E130E03383A1 +:102FD00022832AE932E03583248329853A853783A1 +:102FE00026832B853C854D855E85621B730B840B88 +:102FF000950B60877187828793870E94C2394DB78E +:103000005EB7445F5F4F0FB6F8945EBF0FBE4DBF13 +:103010006ACE86E692E0B6DB7FCF88E892E0B2DB4C +:10302000BECF282D30E03A8729871901220C331CA6 +:1030300033CF2F923F924F925F926F927F928F92F7 +:103040009F92AF92BF92CF92DF92EF92FF920F9337 +:103050001F93DF93CF93CDB7DEB7CD54D0400FB6DB +:10306000F894DEBF0FBECDBF18D526DBC1D89AD6E7 +:1030700078948FE79AE1A6E081509040A040E1F774 +:1030800000C0000010D58FE79AE1A6E08150904083 +:10309000A040E1F700C00000499B05C04A9903C069 +:1030A0004C9901C015D989E189831C821C8E1BA211 +:1030B0001EA28E010F5F1F4FC80160E00E94B62A5A +:1030C000882309F49FC42FE5822E23E0922EEFD4AB +:1030D000499905C04A9903C04C9B01C05ADCC801FC +:1030E0000E949B05C8010E94AE07222433248091D0 +:1030F0005203882309F078C0F894D0904C03C09014 +:103100004E0310925103789480915303882309F061 +:103110007EC080915103882351F74B9B04C00799CF +:103120006DC0F1010995499918C080911C039091D7 +:103130001D03009771F3019790931D0380931C0367 +:10314000C8010E94AE078FEF94E3ACE0815090403D +:10315000A040E1F700C00000DCCF4A9B49C04C9979 +:10316000D8CF80914A03813009F4A3C2823009F498 +:1031700038C2809168008860809368008091680000 +:103180008460809368008091680084608093680008 +:103190008091680081608093680010924C030ED685 +:1031A00001D671D9882309F4A2CF8091540391E00C +:1031B000892790915503992309F4826082B9459A31 +:1031C000A7E8B3E11197F1F700C000004598B2E419 +:1031D000BA95F1F700C04298E1E0E0935303809183 +:1031E0005203882309F488CF8FE593E0CBDA84CFAC +:1031F00080911C0390911D0301969ECF89B180FFA1 +:1032000090CF86B180FF8DCF31998DCF8ACFED2CB5 +:10321000FF242DB73EB7285030400FB6F8943EBF7C +:103220000FBE2DBFEDB7FEB73196ADB7BEB7129644 +:103230009C928E92119786E1482E512C53824282A5 +:10324000B6EC6B2EB2E07B2E75826482F782E6824A +:103250000E94C2392DB73EB7285F3F4F0FB6F89492 +:103260003EBF0FBE2DBF88E164E064D4C40160E0BE +:1032700044E56CD4AC2CBB248DB79EB708970FB631 +:10328000F8949EBF0FBE8DBFEDB7FEB73196ADB7B8 +:10329000BEB712969C928E92119753824282ABECEB +:1032A0004A2EA2E05A2E55824482B782A6820E94FC +:1032B000C2392DB73EB7285F3F4F0FB6F8943EBFD7 +:1032C0000FBE2DBF88E364E035D4C40160E044E55F +:1032D0003DD480914D038D1509F45CC160914D037F +:1032E000C8014FDCD0924D03C0924F0380E090E0C4 +:1032F000FC01E858FA4C20812D7F2083019688310B +:103300009105B1F780915103882309F0F0CE8091A7 +:103310005003882309F030C13D2D303598F7809156 +:103320005503882309F05BC1F701E45DFE4F24914A +:1033300080915903821710F01092590386B14B996E +:1033400008C3881F8827881F8EAF2C9D902D1124BD +:1033500023969FAF2397A701440F551FCA01880FDB +:10336000991F880F991F880F991F840F951F289602 +:103370008FAF289729969FAF299730E02A9DC001EB +:103380002B9D900D3A9D900D11242C01662457FC25 +:103390006094762C27964CAE5DAE6EAE7FAE2797CE +:1033A0000E2CEF2C000CEE1CFF08000CEE1CFF1C7A +:1033B000AA0CBB1CA294B29460EFB622BA24A62237 +:1033C000BA245E2C5A285FAE852D90E084589E4F1B +:1033D00044575F4FFA01659074902B967FAE6EAEA6 +:1033E0002B972D2D2F7321962FAF2197E22FF0E0F1 +:1033F000E458FE4F34912C963FAF2C97FC01F4918A +:103400002D96FFAF2D972296DFAE22972E96CFAE48 +:103410002E972401F6B0F094FF1CFF24FF1C09F442 +:1034200013C16EAC6F1461F080E464E083D3FF20BD +:1034300009F42FC182E494E060E009D421E02EAFCA +:1034400080915D03813009F42AC18091550388235E +:1034500009F4ABC0E0905903F8946E2C772458E738 +:10346000852E55E3952E860C971CD4018C9181FDF9 +:103470008FC08C9182FD8CC08C9184608C9381E094 +:103480007894882309F441C080915503882309F07A +:10349000F7C02B966EAD7FAD2B9780915903A0900E +:1034A000BB35B090BC35C090BD35D090BE35A80EB0 +:1034B000B11CC11CD11C27968CAD9DADAEADBFAD6E +:1034C0002797A80EB91ECA1EDB1E80E090E020914F +:1034D000580330E040E050E00E940A39A60EB71EC3 +:1034E000C81ED91EE0D280917535882309F4B7C073 +:1034F000C801B601A5012E2DFADAD9D2D4018C91DA +:1035000082608C938C918B7F8C938091590388235C +:1035100001F5FF2059F085B1B8E08B2785B980917E +:103520005D03823018F0815080935D0320915C032D +:10353000275E20935C032D3708F08CC030E080912B +:103540005A0390915B03821B930B909389008093A5 +:10355000880080915503882379F122E3F22E06C07A +:103560008EE40E94850FFA9409F4BCC08091510347 +:103570008823B1F34201BBCD80E464E0DBD288E470 +:1035800094E060E064D3809151038823E1F3BACEE4 +:1035900080E076CF80915503882309F4B3CE8091E3 +:1035A0004F038C1509F09ACEADCEE09059032396C7 +:1035B0003FAD2397E30E50CFB7E3EB2EF12C0AC0BB +:1035C0008FEF0E94510F0894E108F108E114F10413 +:1035D00009F4EFC080915103882391F3CBCF22E10E +:1035E000A7CE80914B03815080934B03C80161E0CB +:1035F0000E943C2A80914B03882389F0FF249F2D51 +:10360000ADE09A9FB00111246B587E4CC80141E097 +:103610000E945A2AF39480914B03F81680F310927B +:103620001D0310921C03BED3C8010E949B05C80154 +:103630000E94AE078FEF99E6A8E181509040A0402C +:10364000E1F700C0000053CDC80122966FAD22976C +:1036500098DAE7CE10925C0320E030E070CF93015F +:10366000322F2227330F2B583C4FC801B601A5013A +:103670003CD5882309F041CF87ED91E083D83DCF39 +:1036800028969FAD289729968FAD2997692F782F77 +:1036900004CF8CE394E060E0DAD22B9A1EAE109255 +:1036A0005D0380E065E046D286E294E060E0CFD240 +:1036B000CCCEF0904B03AF2DBDE0AB9FC0011124E9 +:1036C0008B589E4C6EE173E04DE050E00E94B339A0 +:1036D000F394F0924B03C8016EE173E041E00E9465 +:1036E0005A2A9DCF9CE0F92E80915103882309F03E +:1036F00041CF0E94850FFA94B9F7EFEFFFEFF093F7 +:103700005703E09356030E94600F0E94600F0E94CF +:10371000600F80915103882309F02CCF8EEF0E9417 +:10372000850F80915103882309F024CF22968FAD15 +:1037300022970E94850F80915103882309F01ACFA8 +:103740002E968FAD2E970E94850F8091510388236E +:1037500009F010CF809159038F5F0E94850F8091EF +:103760005103882309F006CF82E00E94850FF09074 +:1037700056038091570390915103992309F0FACE93 +:103780000E94850F80915103882309F0F3CE8F2D7D +:103790000E94850FFF2408C08EE40E94850FF394D9 +:1037A000FF2DF63109F4F1C0809151038823A1F374 +:1037B000E1CE80915803823009F4E4C0F2E0FF2E9C +:1037C000E090590380915103882309F0D3CE85ED11 +:1037D0000E94510F80915103882309F0CBCE8AEAD1 +:1037E0000E94510F80915103882309F0C3CE86E9CE +:1037F0000E94510F80915103882309F0BBCE2C9673 +:103800008FAD2C970E94510F80915103882309F0AE +:10381000B1CEE0915903F0E0E458FE4F84910E944C +:10382000510F80915103882309F0A4CE2D968FADBE +:103830002D970E94510F80915103882309F09ACE51 +:10384000EF2DF0E0E458FE4F84910E94510F8091DB +:103850005103882309F08ECE2196EFAD2197EE25F6 +:103860002FADE227EF25EF73F0E0E458FE4F84918F +:103870000E94510F80915103882309F07BCE8EED79 +:103880000E94510F80915103882309F073CE8AEA78 +:103890000E94510FEAE0FE2E80915103882309F027 +:1038A00069CE8FEF0E94510FFA94B1F780915103C6 +:1038B000882309F05FCE85ED0E94510F809151035E +:1038C000882309F057CE8AEA0E94510F8091510354 +:1038D000882309F04FCE8DEA0E94510F8091510349 +:1038E000882309F047CEE0915903F0E0E458FE4FF9 +:1038F00084910E94510FC301982F8827990F8B58EC +:103900009C4F0E94AC0F80915103882309F032CE66 +:103910008EED0E94510F80915103882309F02ACE29 +:103920008AEA0E94510F80915103882309F022CE28 +:103930008FEF0E94510F22968FAD2297609159030D +:10394000A1D8809359034B9B65CD2296DFAC22977B +:1039500042014598429A10925303C8016D2D11D926 +:103960008FE79AE1A6E081509040A040E1F700C0C7 +:1039700000000E945C13C8010E949B05C8010E94C0 +:10398000AE07B5CBA2E2FA2E1BCFFF2480915103E4 +:10399000882309F0EFCD0E94850FF3942F2D2C3052 +:1039A000A9F78FEF9FEF90935703809356030E94E0 +:1039B000600F0E94600F0E94600F80915103882366 +:1039C00009F0D8CD8BEF0E94850F6301DC2CCC244D +:1039D000DD0CA5E7B3E0CA0EDB1EEE24FF240AC00F +:1039E0000E94850F0894E11CF11CF0E0EF16F2E054 +:1039F000FF06B9F1F60181916F019091510399236E +:103A000079F3B8CDADB7BEB71A970FB6F894BEBF6D +:103A10000FBEADBFEDB7FEB731969FE5892E93E09F +:103A2000992E12969C928E92119786E190E0938344 +:103A3000828382EB92E095838483898186831782D7 +:103A40008B81808711860E94C239EDB7FEB73A9606 +:103A50000FB6F894FEBF0FBEEDBFC4010E94C213A3 +:103A600036CBF090560380915703909151039923E0 +:103A700009F080CD0E94850F80915103882309F0C1 +:103A800079CD8F2D0E94850F56CF81E090E00C9468 +:103A9000770980E090E00C94770914BC83E085BD41 +:103AA00081E085BB089581E080936E0008951092B7 +:103AB0006E0008951F920F920FB60F9211248F93EC +:103AC0009F93AF93BF938091C3359091C435A091DC +:103AD000C535B091C6350196A11DB11D8093C33582 +:103AE0009093C435A093C535B093C635BF91AF91BF +:103AF0009F918F910F900FBE0F901F9018952FB729 +:103B0000F8946091C3357091C4358091C53590911A +:103B1000C6352FBF089590E59CBD1DBC882341F09C +:103B20005E9A2A986EBD0DB407FEFDCF2A9A0895BD +:103B30005E98F7CF1F93162F682F606880E0EBDF49 +:103B4000612F606480E0E7DF1F910895AF92BF921C +:103B5000CF92DF92EF92FF920F931F93CF93DF9359 +:103B6000D62EC42EE82EF92EBB248FE7A82EF701FF +:103B700001917F01002359F4DF91CF911F910F91A3 +:103B8000FF90EF90DF90CF90BF90AF900895BC145E +:103B900098F70D3609F183E0089F80011124E801B0 +:103BA000CB52DA4F09521A4FFE016491660FD110C1 +:103BB0006A2581E0B0DFB394C017D10749F4BC1483 +:103BC000B0F6DD20C1F16FE781E0A5DFB394CFCF80 +:103BD0002196BC1460F6E8CFDD2079F163E481E042 +:103BE0009ADFB394BC1408F0C2CFDD2051F16BE72B +:103BF00081E091DFB394BC1408F0B9CFDD2029F146 +:103C000067E681E088DFB394BC1408F0B0CFDD2014 +:103C1000D1F06BE781E07FDFB394BC1408F0A7CF4D +:103C2000DD2069F067E481E076DFB394BC1408F02E +:103C30009ECFDD2041F660E0C7CF6CE3D0CF68E3D4 +:103C4000F2CF64E0D5CF64E0E5CF68E1DACFCF9280 +:103C5000DF92EF92FF920F931F93CF93DF93D62EB5 +:103C60008C010F5F1F4F2FE7C22EF8013197E491AF +:103C7000EE2331F1ED3679F183E0E89FF001112474 +:103C8000EF01CB52DA4F98EDE92E95E0F92EEE0ECA +:103C9000FF1EFE016491660FD1106C2581E03BDFB1 +:103CA0002196CE15DF05A9F7DD2099F06FE781E0B9 +:103CB00032DF0F5F1F4FF8013197E491EE23D1F609 +:103CC000DF91CF911F910F91FF90EF90DF90CF90F8 +:103CD000089560E0ECCFDD2089F081E063E41BDF34 +:103CE00081E06BE718DF81E067E615DF81E06BE7D5 +:103CF00012DF81E067E40FDF6FE7D9CF81E06CE38B +:103D00000ADF81E064E007DF81E068E104DF81E051 +:103D100064E001DF81E068E3FEDE60E0C8CFEF929F +:103D2000FF920F931F93CF93DF93E82EF92EF701A5 +:103D300001917F010023E1F00D3609F183E0089F36 +:103D400080011124E801CB52DA4F08521A4FFE01CC +:103D50006491606481E0DFDE2196C017D107B9F776 +:103D600081E060E4D8DEF70101917F01002321F7B3 +:103D7000DF91CF911F910F91FF90EF90089581E017 +:103D80006EE5C9DE81E062E4C6DE81E06CE4C3DE9C +:103D900081E062E4C0DE81E06CE5BDDE81E060E4EC +:103DA000BADEC5CFCF93DF93C8EFD1E081E060E00A +:103DB000B2DE2197D9F7DF91CF9108958FEB8093F1 +:103DC000C73584E18093C83584E08093C935569A1D +:103DD000279A259A229A209A2A98289A8FE798E378 +:103DE000A1E081509040A040E1F700C00000289879 +:103DF0008FE798E3A1E081509040A040E1F700C038 +:103E00000000289A8FE798E3A1E081509040A040FD +:103E1000E1F700C0000080E090E00E94023C813F9A +:103E2000E1F080E090E061EF0E940A3C6091C735CC +:103E300081E090E00E940A3C80E061E26CDE6091EB +:103E4000C73580E068DE6091C83580E064DE80E0E0 +:103E500060E261DE80E06CE05ECE81E090E00E9496 +:103E6000023C8093C735E8CFFC014181842F90E06C +:103E70009C013595279520652CBD40FD06C081E04D +:103E8000463019F08DBD2C98089580E08DBD2C989A +:103E90000895BF92CF92DF92EF92FF920F931F93FC +:103EA000CF93DF938C016B017A0129DEEB01BB24F8 +:103EB000BA94BEBC0DB407FEFDCF8EB5F801828367 +:103EC0008F3FB1F41CDE6C1B7D0B81E06D327807F7 +:103ED00080F381E1F80180832C9A80E0DF91CF911B +:103EE0001F910F91FF90EF90DF90CF90BF900895BA +:103EF0008E3F19F08FE08083EFCFE114F104F1F0F1 +:103F00000894E108F1088FEF8EBDE114F10471F01F +:103F1000F60180E090E03FEF0DB407FEFDCF2EB537 +:103F200021933EBD01968E159F05B0F30DB407FE9B +:103F3000FDCF8EB5F601EE0DFF1D80838FEF8EBD98 +:103F40000DB407FEFDCF8EB58FEF8EBD0DB407FE0D +:103F5000FDCF8EB52C9A81E0C1CF0F931F93CF93E5 +:103F6000DF93EC018B0180DFCE01B80140E052E02D +:103F700090DFDF91CF911F910F910895FF920F93E2 +:103F80001F93CF93DF93EB01BADD8B01FF24FA94EB +:103F9000FEBC0DB407FEFDCF8EB58F3F69F0AFDDDF +:103FA000601B710B6C177D0798F380E0DF91CF9158 +:103FB0001F910F91FF90089581E0DF91CF911F91A4 +:103FC0000F91FF900895DF92EF92FF920F931F934E +:103FD000CF93DF93EC01D62E79018A0145DFCE0124 +:103FE0006CE271E0CBDF8D2D80648EBD0DB407FED9 +:103FF000FDCF28E130E0D801C701022E04C0B695FC +:10400000A795979587950A94D2F78EBD0DB407FEB4 +:10401000FDCF285030408FEF283F380761F7DD2073 +:10402000E9F08D2D883001F587E88EBD0DB407FECF +:10403000FDCF8D2D8C30D1F02FEF9FEF9EBD0DB4B5 +:1040400007FEFDCF8EB58A8387FD0AC0DF91CF9131 +:104050001F910F91FF90EF90DF90089585E9E5CFD4 +:104060002223A1F32150EACF8FEFDFCF8FEF8EBD58 +:104070000DB407FEFDCF8EB5DFCFCF93DF93EC01FC +:10408000F3DECE016CE020E030E0A9019CDF882364 +:1040900039F083E088832C9A80E0DF91CF910895F6 +:1040A0002C9A81E0DF91CF910895CF93DF93EC01BB +:1040B0009A01AB018B81833039F069E0220F331F05 +:1040C000441F551F6A95D1F7CE0162E17CDF88233A +:1040D00039F085E088832C9A80E0DF91CF910895B4 +:1040E0002C9A81E0DF91CF910895CF92DF92EF92E9 +:1040F000FF920F931F93CF93DF93EC017A018B0113 +:1041000069018B81833039F0A9E0EE0CFF1C001FA0 +:10411000111FAA95D1F7CE0161E1A801970153DFE4 +:10412000882369F084E088832C9A80E0DF91CF9126 +:104130001F910F91FF90EF90DF90CF900895CE01E7 +:10414000B60140E052E0A5DEF1CF8F929F92BF9280 +:10415000CF92DF92EF92FF920F931F93DF93CF9353 +:104160000F92CDB7DEB74C01B62EFC011382108240 +:10417000C6DC8B01249A2C9A2698259A279A249A91 +:104180002C9A85E0F401818382E58CBD1DBC8AE018 +:104190009FEF9EBD0DB407FEFDCF8150D1F7C40146 +:1041A00060E020E030E0A9010EDF782FF401828387 +:1041B0008130C9F0A4DC601B710BF7E0613D7F0723 +:1041C00070F381E0F40180832C9A80E00F90CF910E +:1041D000DF911F910F91FF90EF90DF90CF90BF90F4 +:1041E0009F908F900895C40168E02AEA31E040E092 +:1041F00050E07983E8DE798182FF1FC0F401738388 +:10420000CC24DD247601C40167E320E030E0A9017D +:10421000DADEC40169E2A7019601D5DEF4018283EA +:104220008823D9F06CDC601B710BF7E0613D7F07E0 +:1042300050F38AE0F4018083C7CF84E02FEF2EBDD6 +:104240000DB407FEFDCF9EB5F40192838150B9F7FE +:104250009A3A79F082E08083B7CF83818230B1F0DF +:104260002C9AFB2DF73070F088E1F401808380E018 +:10427000ADCF82E0F4018383C12CD12CE12CB0E4DA +:10428000FB2EC1CFF401B18281E0A0CFC4016AE36B +:1042900020E030E0A90197DE882321F088E0F401D6 +:1042A000808392CF8FEF8EBD0DB407FEFDCF8EB50C +:1042B000807C803C19F483E0F401838383E09FEFEA +:1042C0009EBD0DB407FEFDCF2EB58150C9F7C8CFF6 +:1042D000FC016EBDA42FB52F80E090E00DB407FE69 +:1042E000FDCF2C912EBD0DB407FEFDCF11962C9164 +:1042F00011972EBD0296129622E08030920771F738 +:104300000DB407FEFDCF8FEF8EBD0DB407FEFDCFC0 +:104310008FEF8EBD0DB407FEFDCF8FEF8EBD0DB4B8 +:1043200007FEFDCF8EB582838F71853029F083E142 +:1043300080832C9A80E0089581E008950F931F9365 +:10434000CF93DF93EC018B018FDDCE0168E572E046 +:1043500015DE882349F485E188832C9A80E0DF917B +:10436000CF911F910F910895CE016CEFA801B0DF9E +:10437000882389F32C9A81E0DF91CF911F910F91CF +:104380000895CF92DF92EF92FF920F931F93CF93F6 +:10439000DF93EC017A018B0169018B81833039F065 +:1043A00089E0EE0CFF1C001F111F8A95D1F7CE018A +:1043B00068E1A801970107DE882369F086E0888319 +:1043C0002C9A80E0DF91CF911F910F91FF90EF9099 +:1043D000DF90CF900895CE016EEFA60179DF88239C +:1043E00079F3CE0168E572E0C9DD882319F487E12D +:1043F0008883E6CFCE016DE020E030E0A901E3DD67 +:10440000882319F086E18883DBCF8FEF8EBD0DB452 +:1044100007FEFDCF8EB58823A9F72C9A81E0D2CF75 +:10442000AF92BF92CF92DF92EF92FF920F931F93C2 +:10443000CF93DF93EC015A016B017801890167E3A7 +:1044400020E030E0A901BFDDCE0167E1A8019701BE +:10445000BADD882379F089E088832C9A80E0DF91A7 +:10446000CF911F910F91FF90EF90DF90CF90BF9071 +:10447000AF9008958B81833039F099E0AA0CBB1C72 +:10448000CC1CDD1C9A95D1F7CE0169E1A6019501FE +:104490009ADD882319F087E08883DFCF2C9A81E0AA +:1044A000DECFCF93DF93EC01DFDCCE0168E572E075 +:1044B00065DD882359F08DEF8EBD0DB407FEFDCF6D +:1044C000CE0168E572E05ADD882339F482E1888301 +:1044D0002C9A80E0DF91CF9108952C9A81E0DF91B2 +:1044E000CF910895CF93DF93EC019C012C5F3F4F58 +:1044F000898D9A8D41E050E060E070E00E94042DCB +:104500008823D9F08D899E89AF89B88D0097A10540 +:10451000B10579F48C819D81AE81BF818D8B9E8B9D +:10452000AF8BB88F89818068898381E0DF91CF91DB +:10453000089581E0DF91CF91089580E0DF91CF91E0 +:104540000895CF92DF92EF92FF921F93CF93DF9364 +:10455000EC0189899A89AB89BC89803E2FEF92074B +:104560002FE1A20720E0B20748F080E0DF91CF9171 +:104570001F91FF90EF90DF90CF900895CE01B2DFB2 +:10458000882399F30E94D82A882379F3E98DFA8D3C +:10459000CC80DD80EE80FF808EEF9FEFAFEFBFEF2E +:1045A000C80ED91EEA1EFB1E058404C0CC0CDD1CFF +:1045B000EE1CFF1C0A94D2F786859785A089B189E5 +:1045C000C80ED91EEA1EFB1E81E08093D637C0922A +:1045D000D035D092D135E092D235F092D33580E00B +:1045E00092E0E4EDF5E3DF019C011D9221503040A3 +:1045F000E1F7E98DFA8D84818230C0F011E006C0C8 +:104600001F5FE98DFA8D8481181780F4B701A60128 +:10461000410F511D611D711D8091D4379091D53787 +:1046200024ED35E3AEDE882359F79FCF20E032E05A +:1046300040E050E0058404C0220F331F441F551F83 +:104640000A94D2F789899A89AB89BC89820F931F12 +:10465000A41FB51F898B9A8BAB8BBC8B81E086CF57 +:10466000CF93DF93EC018C859D85AE85BF8541E0BE +:10467000662309F440E0BC01CD01DAD7882381F03C +:10468000288930E0220F331F22953295307F322760 +:10469000207F32272C523A4CC901DF91CF910895E7 +:1046A00020E030E0C901DF91CF9108956F927F92B1 +:1046B0008F929F92AF92BF92CF92DF92EF92FF9232 +:1046C0000F931F93DF93CF9300D000D0CDB7DEB709 +:1046D0006C014B013A01DC015596ED90FD900D9176 +:1046E0001C915897E114F10401051105F1F05E01E8 +:1046F0000894A11CB11C10C0D801C7010196A11DCE +:10470000B11D29813A814B815C8182179307A407EF +:10471000B507F9F47C018D01F601818D928DB80108 +:10472000A7019501CAD7882339F780E00F900F9031 +:104730000F900F90CF91DF911F910F91FF90EF900D +:10474000DF90CF90BF90AF909F908F907F906F90B1 +:104750000895D60159966D917C915A97FB018789EE +:10476000803109F44CC0283F8FEF38078FEF48079E +:104770008FE05807D0F2F60185899689A789B08D18 +:104780000297A109B109FB01058404C0880F991F94 +:10479000AA1FBB1F0A94D2F7268537854089518905 +:1047A000820F931FA41FB51FF40180839183A283FE +:1047B000B383FB0186859785A089B1890197A109FB +:1047C000B1092481820F911DA11DB11DA80197017E +:1047D0002250304040405040058404C0220F331F17 +:1047E000441F551F0A94D2F7820F931FA41FB51FB1 +:1047F000F30180839183A283B38381E097CF283F25 +:10480000FFEF3F07F0E04F07F0E05F0708F0B3CF9E +:104810008CCFE82FF92F80E090E03EE209C0DB0169 +:10482000A90FB11D2C939F5F8F5F31968B3061F084 +:1048300020812032C9F3883091F7DB01A90FB11D27 +:104840003C939F5F2081EBCF690F711DFB011082AC +:1048500008951F93FB012BE030E231932150E9F7DB +:10486000A82FB92F30E017E09A2F8B2F2D912223FC +:1048700051F4FA019083818381E0FB0190819032B1 +:1048800079F01F9108952F32A1F32E3261F082E565 +:1048900097E0FC010196E491EE2351F02E17C9F741 +:1048A00080E01F9108951A30D9F338E01AE0DCCF88 +:1048B0001317B0F32132A0F32F3790F7FB01E30F6A +:1048C000F11D822F81568A3108F4205220833F5FE8 +:1048D000CBCF0F931F93CF93DF93EC018B018B8191 +:1048E000882331F4FB018789803141F08032F1F176 +:1048F00080E0DF91CF911F910F91089582E08B832B +:104900001D8A1E8A1F8A188E808D918DA0E0B0E0CE +:10491000880F991FAA1FBB1F880F991FAA1FBB1FB3 +:10492000880F991FAA1FBB1F880F991FAA1FBB1FA3 +:10493000880F991FAA1FBB1F898B9A8BAB8BBC8BCF +:104940001A8F098F81E089831C821D821E821F823B +:10495000188619861A861B861C861D861E861F864B +:10496000188ADF91CF911F910F91089583E08B8377 +:10497000F801428D538D648D758D4D8B5E8B6F8BE1 +:10498000788F9E012F5E3F4FC80124D78823C1F640 +:10499000AFCF2F923F924F925F926F927F928F9202 +:1049A0009F92AF92BF92CF92DF92EF92FF920F93BE +:1049B0001F93CF93DF938C01362FE72F2A01DC0161 +:1049C00013962C911397222329F011968C9111970D +:1049D00080FD16C02FEF3FEFC901DF91CF911F91EE +:1049E0000F91FF90EF90DF90CF90BF90AF909F908E +:1049F0008F907F906F905F904F903F902F90089591 +:104A0000E801C988DA88EB88FC88488559856A8579 +:104A10007B854201AA24BB24D701C601841B950BC8 +:104A2000A60BB70B88169906AA06BB0608F093C01A +:104A30004114510409F4BEC0832E9E2E6201A4E0ED +:104A40002A2E312C200E311E612CF2E07F2E60C008 +:104A5000FF2009F07AC0411551056105710509F083 +:104A6000ABC0E8018D899E89AF89B88D8C839D8309 +:104A7000AE83BF8346855785608971894F0D511D6F +:104A8000611D711D0297A109B109058404C0880F39 +:104A9000991FAA1FBB1F0A94D2F7480F591F6A1FFC +:104AA0007B1FE301CA19DB09CC16DD0608F4E60119 +:104AB000E2E0C030DE0709F452C0CB01BA0140E0A9 +:104AC000B7D5882309F486CF95012C523A4CC401FE +:104AD000B901AE010E949C39AE0160E070E0F801BE +:104AE00080859185A285B385480F591F6A1F7B1F5A +:104AF000D80118964D935D936D937C931B97CC1AB8 +:104B0000DD0A09F457C08C0E9D1E13962C91139745 +:104B1000EFEFAE2EE1E0BE2EA422B5222230B9F195 +:104B2000D8015996ED91FC915A97DB01CA0129E011 +:104B3000B695A795979587952A95D1F7F480FA941D +:104B4000F822A114B10409F483CFE8018C819D817E +:104B5000AE81BF818FCF2601441A550A69CF80915B +:104B6000D0359091D135A091D235B091D335481739 +:104B700059076A077B0709F4A0CF8091D437909139 +:104B8000D5379401B2DA882309F0A6CF23CF39E0D4 +:104B900076956795579547953A95D1F7E801E98D50 +:104BA000FA8D828D938DA48DB58D480F591F6A1F84 +:104BB0007B1F77CF920110CFD80114964D915D9154 +:104BC0006D917C911797CF01910177D5882309F4D6 +:104BD00001CFE801E98DFA8D8C819D81AE81BF8185 +:104BE00049CFDF93CF930F92CDB7DEB7BE016F5F92 +:104BF0007F4F41E050E0CDDE8130910539F02FEF5D +:104C00003FEFC9010F90CF91DF910895298130E0E6 +:104C1000C9010F90CF91DF910895EF92FF920F930A +:104C20001F93CF93DF93EC018B81823050F420E00F +:104C300030E0C901DF91CF911F910F91FF90EF906C +:104C40000895E884F9840A851B85CE01CADF97FDA3 +:104C5000EECF88859985AA85BB854F96A11DB11D8C +:104C600088879987AA87BB87D801C70115E0B695C1 +:104C7000A795979587951A95D1F78F70282F30E0D3 +:104C8000220F331F22953295307F3227207F322723 +:104C90002C523A4CCECF8F929F92AF92BF92CF922E +:104CA000DF92EF92FF920F931F93CF93DF93EC016C +:104CB0004A015B012B81222309F465C089899A8905 +:104CC000AB89BC8984179507A607B70708F45BC0B2 +:104CD000223009F452C081149104A104B10409F4F2 +:104CE0006AC0488559856A857B85E98DFA8D258559 +:104CF00030E0275F3F4FDB01CA010197A109B109ED +:104D0000022E04C0B695A795979587950A94D2F779 +:104D1000850174010894E108F1080109110904C032 +:104D200016950795F794E7942A95D2F7E816F906B1 +:104D30000A071B07B0F58D899E89AF89B88D8C83D2 +:104D40009D83AE83BF8384E0C82ED12CCC0EDD1EA4 +:104D50000FC04C815D816E817F81898D9A8D960116 +:104D6000ACD40894E108F10801091109882359F02D +:104D7000E114F1040105110561F788869986AA8678 +:104D8000BB8681E001C080E0DF91CF911F910F9140 +:104D9000FF90EF90DF90CF90BF90AF909F908F905B +:104DA0000895411551056105710529F2E81AF90ABE +:104DB0000A0B1B0BC8CF1C821D821E821F82188605 +:104DC00019861A861B8681E0DFCF0F931F93CF933E +:104DD000DF93EC018B81882349F0898187FD0EC028 +:104DE000E7D3DF91CF911F910F91089581E08883E0 +:104DF00080E0DF91CF911F910F910895CE0161E086 +:104E00002FDC8C01009791F3FC018081853E71F3CA +:104E10008B818230F8F08D899E89AF89B88DF80139 +:104E2000938F828FB58BA48BE091CC35F091CD35EB +:104E3000309759F0B8016A5E7F4FC80148960995CE +:104E4000F801808D918D938B828B89818F778983F7 +:104E5000AFD3C7CF89899A89AB89BC89848F958F55 +:104E6000A68FB78FD8CFCF93DF93EC01AEDF1B8235 +:104E7000DF91CF9108956F927F928F929F92AF9220 +:104E8000BF92CF92DF92EF92FF920F931F93DF9327 +:104E9000CF9300D000D0CDB7DEB77C015A016B01B3 +:104EA000DC0113968C9113978130A1F080E00F9074 +:104EB0000F900F900F90CF91DF911F910F91FF9066 +:104EC000EF90DF90CF90BF90AF909F908F907F90AA +:104ED0006F90089511968C91119781FFE7CFF7019C +:104EE00081899289A389B48984179507A607B70792 +:104EF000E8F20097A105B10529F1F70160847184FA +:104F000082849384C701B601A501C5DE882371F2AE +:104F1000A114B104C104D104B9F4D70155964D913F +:104F20005D916D917C91589759968D919C915A976E +:104F3000A3D6882309F4BACFF701158A168A178AEF +:104F4000108E40C081E0B3CFD70114964D915D9192 +:104F50006D917C91179759968D919C915A979E01CE +:104F60002F5F3F4FAAD3882309F4A0CFD7015996CA +:104F7000ED91FC915A9749815A816B817C81878997 +:104F80008031C9F1483F8FEF58078FEF68078FE0F6 +:104F90007807C0F4CF0170D6882309F487CFD701F2 +:104FA00014964D915D916D917C91179759968D91C5 +:104FB0009C915A970FEF1FEF2FEF3FE086D4882385 +:104FC00009F474CFF701A18AB28AC38AD48A818195 +:104FD00080688183C701F9DE882309F467CFB601B1 +:104FE000A5016A147B048C049D0410F4B401A30190 +:104FF000C70151DE5CCF483FBFEF5B07B0E06B07F6 +:10500000B0E07B07F8F6C6CF1F93CF93DF93EC0198 +:10501000142FE62FF0E0EE0FFF1FE295F295F07FE0 +:10502000FE27E07FFE27DF01AC52BA4C1B968C9125 +:105030001B97817149F0842F827131F01B8280E0CF +:10504000DF91CF911F9108958091D0359091D13506 +:10505000A091D235B091D3358C879D87AE87BF871D +:10506000688BEC52FA4C84899589A0E0B0E0DC01B1 +:10507000992788278D8B9E8BAF8BB88F428D538D50 +:1050800060E070E0482B592B6A2B7B2B4D8B5E8B9D +:105090006F8B788F838590E0887190700097F1F422 +:1050A000848D958DA68DB78D898B9A8BAB8BBC8BA0 +:1050B00081E08B83812F8F7089831C821D821E82E9 +:1050C0001F82188619861A861B8614FD17C015FDC7 +:1050D0001EC081E0DF91CF911F910895803191052D +:1050E00009F0ACCF9E012F5E3F4F898D9A8D72D310 +:1050F000882309F4A3CF84E08B83DCCFCE0140E08A +:1051000050E0BA01B8DE882311F780E099CF4989D1 +:105110005A896B897C89CE01BEDD92CF8F929F9296 +:10512000AF92BF92CF92DF92EF92FF920F931F93B5 +:10513000CF93DF935C01EB01C42E952E822E898DD7 +:105140009A8DD5015A969C938E935997CB0140E046 +:1051500050E0BA01A0DDDD24E884F9840A851B85CE +:1051600089899A89AB89BC89E816F9060A071B0761 +:1051700008F040C0CE0151DDFC01009709F476C073 +:10518000D801C70115E0B695A795979587951A950B +:10519000D1F7182F1F708081882391F0853E81F010 +:1051A0008C2D992DBF014BE050E00E948F39009764 +:1051B00099F687FC5BC0C501612F482D25DF57C0DC +:1051C000DD20A9F42091D0353091D1354091D235F0 +:1051D0005091D335D5011C962D933D934D935C93FF +:1051E0001F9750961C9350978081DD24D394882379 +:1051F00009F0B2CF86FE3AC081FE38C0DD2009F04A +:1052000043C08B81823091F1CE019BD9882371F10B +:10521000C4EDD5E310E07E01EC2FFF2D80E2DF012D +:105220001D928A95E9F7DE018C2D992DFC018BE00A +:1052300001900D928150E1F7E091CC35F091CD35A0 +:10524000309761F1BE01625F7F4FCE0140960995B4 +:10525000888999892E853F859B8B8A8B998F888F2A +:105260003F8B2E8BA5D1882309F0A5CF80E0DF915D +:10527000CF911F910F91FF90EF90DF90CF90BF9053 +:10528000AF909F908F900895F5011089C50161E05E +:10529000E7D9EC01009709F0BECFE8CF81E298E2B0 +:1052A000998B888B80E098E09F878E8720E038E09C +:1052B00081E298E2D1CF2F923F924F925F926F920C +:1052C0007F928F929F92AF92BF92CF92DF92EF9296 +:1052D000FF920F931F93DF93CF93CDB7DEB7C454E4 +:1052E000D0400FB6F894DEBF0FBECDBF2C013B01FE +:1052F0008E010E5B1F4FD80111965C934E9325963D +:105300002FAF25971C861F861FA21AA6611571054F +:1053100009F45FC0FC018381882309F05AC0CA01E7 +:10532000DA012C912F3209F470C073013CE0832E16 +:10533000912C8C0E9D1E64015E010894A11CB11C71 +:1053400027E2222E312C2C0E3D1EB501A80181DA58 +:10535000882369F1D801ED91FC91119780818F32FA +:1053600041F43196D8011196FC93EE9381918F32DE +:10537000C9F3882309F46FC0C601B701A50121E074 +:10538000CDDE8823A1F0E614F70421F0C7011DDD6E +:10539000F7011382C814D904C9F076016401D80159 +:1053A0008D919C91B501A80154DA882399F600E00B +:1053B0008AA5882321F0CE01879607DD1AA68F855E +:1053C000882341F0CE010C9600DD04C06101740118 +:1053D000E6CF00E0802FCC5BDF4F0FB6F894DEBF46 +:1053E0000FBECDBFCF91DF911F910F91FF90EF9036 +:1053F000DF90CF90BF90AF909F908F907F906F90F5 +:105400005F904F903F902F9008959A012F5F3F4FEC +:10541000C901F80131832083D9014C912F5F3F4F9F +:105420004F32B1F3F30123812250223008F47DCFB3 +:1054300087E2E82EF12CEC0EFD1ED30159966D91FA +:105440007C915A97C70145DA882309F4B0CFF80157 +:10545000808191816BCFC201B701A50125962FAD47 +:1054600025975CDE082FA4CFFB01242F6091CA355D +:105470007091CB35AF011FCF0F931F93CF93DF9365 +:10548000EC01662399F08C010E5D1F4F1093CB3514 +:105490000093CA35C801E7DCBE016C5F7F4FC801CD +:1054A00018DADF91CF911F910F9108958C010E5D55 +:1054B0001F4FF0CFDF92EF92FF920F931F93DF9376 +:1054C000CF93CDB7DEB76C970FB6F894DEBF0FBEA3 +:1054D000CDBFFB01D42E19821C8220812F3229F1ED +:1054E00022E2E22EF12CE80EF91E8E010F5F1F4F13 +:1054F000C801B701AF0121E0DEDE8823F1F08C8125 +:10550000823070F1D701F8018BE101900D9281504A +:10551000E1F7DD2021F0F092CB35E092CA3521E0B1 +:10552000C8012C8FA0DC2C8D0CC021812223C1F658 +:10553000642FA2DF282F8C8102C08C8120E0882379 +:1055400089F4822F6C960FB6F894DEBF0FBECDBFE4 +:10555000CF91DF911F910F91FF90EF90DF90089511 +:1055600020E0EDCF8E010F5F1F4FDACF0F931F9317 +:10557000CF93DF938C010E94A520882331F480E033 +:10558000DF91CF911F910F910895E8012496CE01EC +:10559000B80141E0CDD3882321F0C80161E06CDF80 +:1055A000EFCFCE01B80140E0C3D3882341F3F5CF5C +:1055B0008091D637882311F481E008954091D03549 +:1055C0005091D1356091D2357091D3358091D437D7 +:1055D0009091D53724ED35E30E94C121882321F134 +:1055E0004091D7375091D8376091D9377091DA37D9 +:1055F000411551056105710521F41092D63781E0FE +:1056000008958091D4379091D53724ED35E30E94E9 +:10561000C121882359F01092D7371092D8371092B1 +:10562000D9371092DA37E9CF80E0089580E0089505 +:10563000DF92EF92FF920F931F937B018C01D42E88 +:105640008091D0359091D135A091D235B091D3359C +:105650008E159F05A007B107F1F0AADF882339F462 +:1056600080E01F910F91FF90EF90DF90089580915F +:10567000D4379091D537B801A70124ED35E30E94C6 +:105680007520882369F3E092D035F092D1350093EC +:10569000D2351093D335DD2049F081E08093D637A1 +:1056A0001F910F91FF90EF90DF90089581E01F917F +:1056B0000F91FF90EF90DF900895CF92DF92EF92DD +:1056C000FF920F931F93CF93DF93EC017A018B012D +:1056D000690189859A85AB85BC850196A11DB11D9F +:1056E00084179507A607B70730F0EF89E03169F016 +:1056F000E03209F445C080E0DF91CF911F910F9116 +:10570000FF90EF90DF90CF9008959927872F762F05 +:10571000652F2B893C894D895E89620F731F841F19 +:10572000951F2091D0353091D1354091D23550918F +:10573000D335621773078407950729F040E078DFB7 +:105740008823C9F2EF89E03169F18FE790E0A0E0AA +:10575000B0E0E822F9220A231B23F701EE0FFF1F16 +:10576000EE0FFF1FEC52FA4C80819181A281B38130 +:10577000BF70F60180839183A283B38381E0BCCFA5 +:10578000CB01BA0127E096958795779567952A957D +:10579000D1F72B893C894D895E89620F731F841F65 +:1057A000951FBFCF8FEF90E0A0E0B0E0E822F92294 +:1057B0000A231B23F701EE0FFF1FEC52FA4C8081E6 +:1057C0009181A0E0B0E0F60180839183A283B3834E +:1057D00081E092CF4F925F926F927F928F929F92D1 +:1057E000AF92BF92CF92DF92EF92FF920F931F93EF +:1057F000DF93CF9300D000D0CDB7DEB78C014983C3 +:105800005A836B837C832901842F952FA62FB72F72 +:10581000AC01BD01CC24DD2476015E010894A11CFD +:10582000B11C612CE2E07E2E812C912CC8019501E7 +:1058300044DF882309F447C0D401C301F80105847B +:1058400004C0880F991FAA1FBB1F0A94D2F7C80E65 +:10585000D91EEA1EFB1E49815A816B817C81878992 +:10586000803119F1483F8FEF58078FEF68078FE0BD +:105870007807E0F2F201C082D182E282F38281E015 +:105880000F900F900F900F90CF91DF911F910F917C +:10589000FF90EF90DF90CF90BF90AF909F908F9050 +:1058A0007F906F905F904F900895483FFFEF5F07A4 +:1058B000F0E06F07F0E07F07E8F6C8019501FDDE34 +:1058C000882309F0B9CF80E0DBCF4F925F926F92CF +:1058D0007F928F929F92AF92BF92CF92DF92EF9280 +:1058E000FF920F931F93CF93DF93EC016A017B012B +:1058F00028013901423051056105710590F0898513 +:105900009A85AB85BC850196A11DB11D84179507AD +:10591000A607B70730F08F89803109F456C080326E +:1059200091F080E0DF91CF911F910F91FF90EF9068 +:10593000DF90CF90BF90AF909F908F907F906F90AF +:105940005F904F9008954A015B0117E0B694A794C9 +:10595000979487941A95D1F78B899C89AD89BE89D4 +:10596000880E991EAA1EBB1EC501B40141E060DE6F +:105970008823B9F28F898031A9F18FE790E0A0E008 +:10598000B0E0C822D922EA22FB22F601EE0FFF1F67 +:10599000EE0FFF1FEC52FA4C4082518262827382FA +:1059A0008A89823078F18D819E81AF81B885880D9A +:1059B000991DAA1DBB1D8093D7379093D837A0930C +:1059C000D937B093DA3781E0ADCF852E962EA72E4A +:1059D000BB248B899C89AD89BE89880E991EAA1E1D +:1059E000BB1EC2CF8FEF90E0A0E0B0E0C822D9226A +:1059F000EA22FB22F601EE0FFF1FEC52FA4C518215 +:105A00004082CECF81E08ECF2F923F924F925F9215 +:105A10006F927F928F929F92AF92BF92CF92DF92BE +:105A2000EF92FF920F931F93DF93CF93CDB7DEB723 +:105A300067970FB6F894DEBF0FBECDBF1C01498734 +:105A40005A876B877C873E872D87FC0181859285ED +:105A5000A385B4859C01AD012F5F3F4F4F4F5F4F32 +:105A60002D833E834F835887ED85FE85408051808E +:105A700062807380411451046104710409F4BEC052 +:105A80000894411C511C611C711C1F860097A105C4 +:105A9000B10509F454C0D301C201CC24DD24760140 +:105AA0008E010F5F1F4F4C8A5D8A6E8A7F8A2EC0DF +:105AB0004C015D01C101B501A4019801FEDD8823FF +:105AC00009F43DC089819A81AB81BC810097A10511 +:105AD000B10509F44EC0A50194012F5F3F4F4F4F10 +:105AE0005F4F2C8B3D8B4E8B5F8BDA01C901089485 +:105AF000C11CD11CE11CF11CF101218532854385BB +:105B00005485C216D306E406F506C8F44D805E80BF +:105B10006F807884481659066A067B0648F682E04C +:105B2000882E912CA12CB12C8C8A9D8AAE8ABF8A9A +:105B3000C101B501A4019801C0DD882319F680E0F8 +:105B400067960FB6F894DEBF0FBECDBFCF91DF9141 +:105B50001F910F91FF90EF90DF90CF90BF90AF908B +:105B60009F908F907F906F905F904F903F902F907D +:105B70000895D501C4010196A11DB11D2C013D015F +:105B80002C893D894E895F89421A530A640A750A35 +:105B900029853A854B855C85421653066406750651 +:105BA00009F0A5CF4C885D886E887F88C101B5015A +:105BB000A4010FEF1FEF2FEF3FE087DE882309F4EA +:105BC000BECF481459046A047B0458F5950184013A +:105BD00007C0970186014C145D046E047F0408F52C +:105BE000680179010894C108D108E108F108C101F0 +:105BF000B701A6016ADE882361F7A1CFF1014080D9 +:105C0000518062807380F1E0FF8729853A854B855A +:105C10005C85213031054105510509F437CF1F86D8 +:105C200035CFAD85BE854D915D916D917C9113977A +:105C30004115510561057105C1F4ED85FE85408270 +:105C4000518262827382FF85FF2369F00894411CB0 +:105C5000511C611C711CD1014D925D926D927C9220 +:105C6000139781E06DCF81E06BCFC1019301820179 +:105C70002CDE882311F763CFAF92BF92CF92DF92D1 +:105C8000EF92FF920F931F93DF93CF9300D000D03A +:105C9000CDB7DEB76C017A018B0182E090E0A0E025 +:105CA000B0E0F60180839183A283B3835E01089400 +:105CB000A11CB11CC601B801A7019501FEDC882317 +:105CC00039F1C601B801A70100E010E09801FDDD3F +:105CD0008823F1F0E980FA800B811C81F601878925 +:105CE000803159F088EFE8168FEFF8068FEF08073C +:105CF0008FE01807F8F281E00CC0F8EFEF16FFEF25 +:105D0000FF06F0E00F07F0E01F07A0F281E001C0FE +:105D100080E00F900F900F900F90CF91DF911F9127 +:105D20000F91FF90EF90DF90CF90BF90AF900895CC +:105D30006F927F928F929F92AF92BF92DF92EF927B +:105D4000FF920F931F93CF93DF93EC01142F709367 +:105D5000D5376093D4371F8A82E090E0A0E0B0E0AE +:105D600088839983AA83BB831092D6371092D73742 +:105D70001092D8371092D9371092DA378FEF9FEF01 +:105D8000DC018093D0359093D135A093D235B09378 +:105D9000D335442309F444C0453078F080E0DF91E6 +:105DA000CF911F910F91FF90EF90DF90BF90AF9038 +:105DB0009F908F907F906F90089560E070E0CB018E +:105DC00040E036DC882351F3212F30E022953295D4 +:105DD000307F3227207F32272C533A4CF901E2548E +:105DE000FE4F808190E08F7790700097B9F6F901AF +:105DF000E653FE4F80819181A281B3818436910563 +:105E0000A105B10558F22A533E4FF901E080F18017 +:105E100002811381E114F1040105110521F4BECFC3 +:105E2000EE24FF248701C801B70140E001DC88238C +:105E300009F4B4CF8091DF359091E035F2E0803005 +:105E40009F0709F0ABCF2091E435222309F4A6CFB8 +:105E50008091E2359091E335009709F49FCF6091EE +:105E6000E135662309F49ACF2A8B6C831D8670E096 +:105E700080E090E041E050E008C0282F2F5F2D87A0 +:105E800001968930910509F489CFD82E9A01082E00 +:105E900002C0220F331F0A94E2F72617370769F76B +:105EA0006091EA357091EB356115710509F47FC099 +:105EB00080E090E06D837E838F8398878090E235C9 +:105EC0009090E335AA24BB248E0C9F1CA01EB11E0B +:105ED0008B8A9C8AAD8ABE8A6090E5357090E635E3 +:105EE000798E688E2091E43530E040E050E00E94E9 +:105EF0000A39680D791D8A1D9B1D6A8F7B8F8C8FD7 +:105F00009D8F9301220F331F22953295307F3227C8 +:105F1000207F322721503E4F232F3327269540E004 +:105F200050E0260F371F481F591F2E873F87488B89 +:105F3000598B8091E7359091E835009709F440C07E +:105F4000A0E0B0E0E21AF30A040B150BE80EF91E0C +:105F50000A1F1B1F04C016950795F794E794DA945F +:105F6000D2F7E986FA860B871C8725EFE2162FE029 +:105F7000F20620E0020720E0120758F185EFE8164C +:105F80008FEFF80680E0080780E0180730F1809175 +:105F9000003690910136A0910236B09103368A8F77 +:105FA0009B8FAC8FBD8F80E28F8B81E0F8CE6091AC +:105FB000F8357091F9358091FA359091FB357ACFAB +:105FC0008091F4359091F535A091F635B091F73583 +:105FD000B9CF8CE08F8B80E0E2CE80E18F8B81E0C7 +:105FE000DECECF93DF93DC01CD91DC9111971C16AF +:105FF0001D06DCF41296E0E0F0E020E030E0A901BC +:10600000542F432F322F22276D9170E080E090E0D3 +:10601000262B372B482B592B3196EC17FD0781F790 +:10602000B901CA01DF91CF91089520E030E0A901C4 +:10603000F7CFCF93DF93FB01DC012D913C91B901A8 +:106040006E5F7F4FEC01C60FD71FE60FF71FD90118 +:106050001196A40FB51F2115310599F0215030403C +:106060008A9192914115510519F06C9186239623DE +:106070001197891781F320E030E0C901DF91CF91BA +:10608000089521E030E0C901DF91CF910895CF93C9 +:10609000DF93FB0120813181DC012D933C93A081B2 +:1060A000B181109701F1BD01615070401296EA0F65 +:1060B000FB1FEA01CA0FDB1FA80FB91F80E09A91EE +:1060C000229130E0290F311D280F311D81E02F3F33 +:1060D000310509F008F480E02E93615070409FEF85 +:1060E0006F3F790761F7DF91CF910895EF92FF92AB +:1060F0000F931F93CF93DF938B01FC017183608318 +:106100006115710581F022E0E22EF12CE80EF91EF6 +:10611000C0E0D0E0C7018C0F9D1F0E94CE382196B1 +:10612000C017D107B9F7DF91CF911F910F91FF9061 +:10613000EF90089524E030E0FC013783268384E06B +:1061400090E0089521E0FC01208380E090E0089534 +:10615000EF92FF920F931F93DF93CF930F92CDB7E0 +:10616000DEB77C018E010F5F1F4FC8010E94CE3841 +:1061700089818823D1F7F7011782168280E090E0A9 +:106180000F90CF91DF911F910F91FF90EF900895A5 +:106190000F931F93DF93CF930F92CDB7DEB78C0190 +:1061A000CE010196FBD78981823070F085E090E0C6 +:1061B000F8019783868325E030E0C9010F90CF91E5 +:1061C000DF911F910F910895F8019181933141F072 +:1061D000882369F481E0F801828720E030E0EDCF88 +:1061E000882359F481E0818720E030E0E6CF86E023 +:1061F000F801828720E030E0E0CF8DE0F801818770 +:1062000020E030E0DACF0B96C9D780E090E0089527 +:10621000CF93DF93EC016C897D898E559F4F66DFAC +:106220006C897D89CE018B539F4F60DF80E090E0C9 +:10623000DF91CF910895FC016489758981589F4F42 +:1062400055DF80E090E008950F931F93CF93DF9385 +:106250008C01EC016696CE0164E070E047DFCE0170 +:10626000C0DEF801648775878687978780E090E0B5 +:10627000DF91CF911F910F9108950F931F93CF93AB +:10628000DF938C01EC016696CE0164E070E02EDFB6 +:10629000CE01A7DEF801608B718B828B938B695FD7 +:1062A0007F4F8F4F9F4F28E030E040E050E00E944A +:1062B0005F39F801358B248B2132310564F086E09B +:1062C00090E09783868326E030E0C901DF91CF918B +:1062D0001F910F91089520E030E0C901DF91CF9127 +:1062E0001F910F910895BC0181E090E02BD780E0D1 +:1062F00090E060E070E026D780E090E061E070E040 +:1063000021C74F925F926F927F928F929F92AF922E +:10631000BF92CF92DF92EF92FF920F931F93CF9392 +:10632000DF93EC01F62E662309F4A4C0888186175A +:1063300009F4EEC06730C1F06E30C1F48D30B1F0B9 +:1063400005E010E0C801DF91CF911F910F91FF9000 +:10635000EF90DF90CF90BF90AF909F908F907F9005 +:106360006F905F904F900895863051F700E010E0F5 +:10637000A8E0AA2EFCE0CF2EEEE06E2E7FE0B72E36 +:1063800062E0E62E992493945AE0752E45E0D42ECF +:1063900037E0832E23E0422E99E0592EF81691F231 +:1063A000873009F495C08830A8F4833009F453C0CD +:1063B000843008F03CC08130A1F1823008F454C030 +:1063C0008F2D893008F49EC081E090E08CDF5882E8 +:1063D0008881E4CF8B3059F08C3078F4893009F41F +:1063E00067C08A3008F47DC09F2D9B3089F081E022 +:1063F00090E079DFC8828881D1CF8D3009F452C016 +:106400008D3000F18E3009F075C09F2D9B30E9F47E +:1064100080E090E068DFF8828881C0CF8F2D8130E6 +:1064200019F181E090E05FDFE8828881B7CF8530A5 +:1064300009F444C0863090F081E090E054DF888217 +:106440008881ACCF8F2D8D3019F381E090E04BDF48 +:10645000B8828881A3CF9F2D9430D1F281E090E063 +:1064600042DFD88288819ACF80E090E03CDF98823A +:10647000888194CF81E090E036DF00E010E080E09A +:1064800090E060E070E05ED680E090E061E070E077 +:1064900059D60F5F1F4F0530110589F7188200E0AC +:1064A00010E050CF81E090E01EDF6882888176CFD7 +:1064B00080E090E018DF7882888170CF8F2D863061 +:1064C00009F4A6CF81E090E00EDFA882888166CF34 +:1064D0009F2D943009F49CCF81E090E004DFA882E6 +:1064E000F5CF8F2D813009F493CF81E090E0FBDE72 +:1064F000E8829BCF8F3009F491CFF88205E010E05D +:1065000088814CCF80E090E0EEDE4882888146CFE3 +:10651000863049F08D3009F029CF81E090E0E3DE4C +:106520008EE0888323CF81E090E0DDDE87E0888302 +:106530001DCFCF92DF92EF92FF920F931F93CF93D5 +:10654000DF93EC018C010A5E1F4FC80161E070E02F +:10655000CDDDC88CC80161E070E0C8DDD88CC80111 +:1065600064E070E0C3DDC8013CDD7B018C018885FF +:106570008C1521F0CE0108966C2DC3DEC801B70141 +:1065800023D688858D1521F0CE0108966D2DB9DEB4 +:1065900080E090E0DF91CF911F910F91FF90EF90FD +:1065A000DF90CF9008950F931F93DF93CF930F92B7 +:1065B000CDB7DEB78C01CE010196F0D5C8010896A3 +:1065C00069819FDE9C01009719F0F801978386830B +:1065D000C9010F90CF91DF911F910F9108954F92B4 +:1065E0005F926F927F928F929F92AF92BF92CF9263 +:1065F000DF92EF92FF920F931F93CF93DF935B0194 +:106600006C01FA0138012115310509F481C080813E +:106610009181D90111969C938E93808191818C01F7 +:106620000E5F1F4F020F131FA114B104C104D10448 +:1066300009F45DC022E0422E512C480E591E4E0E28 +:106640005F1E0CC00115110519F0D8019E928D0135 +:10665000A114B104C104D10409F449C0F20182902B +:106660002F01EE24FF2499240894A108B108C10841 +:10667000D1086114710429F0A114B104C104D1043A +:1066800081F1C82DD0E0BE016170707082E090E0B1 +:1066900059D580E090E060E070E054D50115110517 +:1066A00049F08ED590E00E2C02C0880F991F0A94F5 +:1066B000E2F7982A80E090E061E070E043D5A11411 +:1066C000B104C104D10409F4BDCF0894E11CF11C4C +:1066D000F8E0EF16F10409F4B5CFD595C7958C2EE7 +:1066E000C3CF81E090E061E070E02CD5CACFDF91AC +:1066F000CF911F910F91FF90EF90DF90CF90BF90BF +:10670000AF909F908F907F906F905F904F90089583 +:106710008081918100E010E087CF2F923F924F92CD +:106720005F926F927F928F929F92AF92BF92CF9221 +:10673000DF92EF92FF920F931F93DF93CF93CDB72A +:10674000DEB728970FB6F894DEBF0FBECDBF3C0171 +:10675000962E29833A834B835C831E830D83170116 +:106760002601B886AF82A9A051E0C52ED12C6815AC +:1067700009F487C029813A814B815C81211531055B +:106780004105510529F58D8D9E8DAF8DB8A10097DE +:10679000A105B10509F097C020E030E0C9012896B5 +:1067A0000FB6F894DEBF0FBECDBFCF91DF911F9122 +:1067B0000F91FF90EF90DF90CF90BF90AF909F90A0 +:1067C0008F907F906F905F904F903F902F900895A3 +:1067D000BB24EE24FF24C301692D93DD69817A81F6 +:1067E0008B819C814D815E8191018601F8DE41148F +:1067F000510461F0C201B1014F8158851ADC41E0BA +:10680000E42EF12C009711F0EE24FF24C114D104E2 +:10681000E9F0D3018C918F5F8C93E114F10459F06E +:106820002D8D3E8D4F8D58A1211531054105510506 +:1068300011F0BA1448F1C301682D63DD8D8D9E8D72 +:10684000AF8DB8A10097A105B10591F4E114F10451 +:1068500009F4A2CFB3948B2D81508A1508F4BBCFD5 +:10686000AA2019F0AB1408F439C022E030E096CF2A +:10687000C30161E046DD6D8D7E8D8F8D98A1A4D41E +:10688000E5CFCC24DD2476CFC30166E03ADDC30139 +:1068900064E037DD8D8D9E8DAF8DB8A1B595A79540 +:1068A00097958795B595A795979587952D8D3E8D4D +:1068B0004F8D58A1280F391F4A1F5B1F2D8F3E8F08 +:1068C0004F8F58A3BBCFC30161E01BDD6D8D7E8D63 +:1068D0008F8D98A179D420E030E060CF23E030E0C4 +:1068E0005DCF8F92AF92BF92CF92DF92EF92FF92E5 +:1068F0000F931F93CF93DF93EC018C010A5E1F4F20 +:106900006C897D89C801F2DB00D000D00F92288904 +:1069100039894A895B89ECE5EE2EF12CEC0EFD1EDF +:1069200079E3C72ED12CCC0EDD1E6FE7A62EB12C3D +:10693000AC0EBD1E8C859D85AE85BF85EDB7FEB7BF +:1069400081839283A383B4838B858583CE0108964C +:1069500064E08A84E2DE9C010F900F900F900F900C +:106960000F90009711F09F838E83C901DF91CF9123 +:106970001F910F91FF90EF90DF90CF90BF90AF905D +:106980008F9008958F92AF92BF92CF92DF92EF9245 +:10699000FF920F931F93CF93DF93EC018C010A5E5C +:1069A0001F4FC80162E070E0A1DBC8011ADB6B0178 +:1069B0007C01695F7F4F8F4F9F4F28E030E040E0C0 +:1069C00050E07DD4213231058CF026E030E03F8369 +:1069D0002E83C901DF91CF911F910F91FF90EF900E +:1069E000DF90CF90BF90AF908F900895C801B9010C +:1069F0007DDB00D000D00F928C859D85AE85BF8554 +:106A0000EDB7FEB781839283A383B4831582CE0151 +:106A100008966BE0A7019601EE24FF24CC24DD2428 +:106A2000AA24BB24898479DE9C010F900F900F90DB +:106A30000F900F90009769F2CACF6F927F928F925A +:106A4000AF92BF92CF92DF92EF92FF920F931F937C +:106A5000DF93CF930F92CDB7DEB73C01CE01019605 +:106A60009DD383010A5E1F4F298130E040E050E052 +:106A7000295F3F4F4F4F5F4FF3E05595479537954F +:106A80002795FA95D1F7C801B90130DB00D000D0C5 +:106A90000F92298130E040E050E0F3018485958534 +:106AA000A685B785EDB7FEB781839283A383B483B0 +:106AB0001582C30108966BE0EE24FF24CC24DD246C +:106AC000AA24BB24F301818428DE9C010F900F903F +:106AD0000F900F900F90009719F0F3019783868322 +:106AE000C9010F90CF91DF911F910F91FF90EF900F +:106AF000DF90CF90BF90AF908F907F906F90089570 +:106B00002F923F924F925F926F927F928F92AF92AD +:106B1000BF92CF92DF92EF92FF920F931F93DF937A +:106B2000CF9300D0CDB7DEB79A8389831A012B01AA +:106B30003901C801B901DADAC114D10419F0C6016A +:106B4000B301D4DA00D000D00F928E899F89A88D2E +:106B5000B98DEDB7FEB781839283A383B4838A8D09 +:106B6000858389819A8164E0A2019101D6DD0F902D +:106B70000F900F900F900F900F900F90CF91DF918B +:106B80001F910F91FF90EF90DF90CF90BF90AF904B +:106B90008F907F906F905F904F903F902F900895CF +:106BA0008F92AF92BF92CF92DF92EF92FF920F93AC +:106BB0001F93CF93DF93EC0189818131D9F114E0E8 +:106BC000812E00D000D00F92488959896A897B892B +:106BD0002C893D898E010A5E1F4FBCE5EB2EF12CFE +:106BE000EC0EFD1EA9E3CA2ED12CCC0EDD1EEDB796 +:106BF000FEB711821282138214821582CE0108968A +:106C0000AA24BB247DDF9C010F900F900F900F9062 +:106C10000F90009711F09F838E83C901DF91CF9170 +:106C20001F910F91FF90EF90DF90CF90BF90AF90AA +:106C30008F9008958A84C5CF8F92AF92BF92CF92E2 +:106C4000DF92EF92FF920F931F93CF93DF93EC01AC +:106C500089818E30A9F104E0802E00D000D00F92FF +:106C6000488959896A897B892C893D898E010A5E08 +:106C70001F4FEDB7FEB71182128213821482158264 +:106C8000CE010896EE24FF24CC24DD24AA24BB24C4 +:106C900037DF9C010F900F900F900F900F9000978F +:106CA00011F09F838E83C901DF91CF911F910F91C6 +:106CB000FF90EF90DF90CF90BF90AF908F900895AE +:106CC0008A84CBCF8F92AF92BF92CF92DF92EF9216 +:106CD000FF920F931F93CF93DF93EC0100D000D06E +:106CE0000F92488959896A897B892C893D898C0151 +:106CF0000A5E1F4FECE5EE2EF12CE80EF91E99E32B +:106D0000C92ED12CCC0EDD1E8FE7A82EB12CAC0ED7 +:106D1000BD1E8C859D85AE85BF85EDB7FEB7818391 +:106D20009283A383B4838B858583CE0108968A845E +:106D3000E7DE9C010F900F900F900F900F9000973F +:106D400011F09F838E83C901DF91CF911F910F9125 +:106D5000FF90EF90DF90CF90BF90AF908F9008950D +:106D6000CF92DF92EF92FF920F931F93CF93DF9317 +:106D70008C016B017901B8018AD9E601288139813A +:106D8000F701A081B181AD014150504057FD38C09D +:106D9000FD013296EE0DFF1D1196A00FB11F60E0B0 +:106DA00010E08291882329F1EC9001E00AC0762F4F +:106DB000660F7123B1F0E02A959587958823C1F07D +:106DC000000F90E080FFF8CF662389F72150304014 +:106DD000B601620F731FEB011A8162E071E071234B +:106DE00051F7702F7095E72295958795882341F785 +:106DF000EC924150504011978FEF4F3F580789F662 +:106E0000DF91CF911F910F91FF90EF90DF90CF9086 +:106E100008952F923F924F925F926F927F928F923E +:106E20009F92AF92BF92CF92DF92EF92FF920F9319 +:106E30001F93DF93CF93CDB7DEB761970FB6F8946A +:106E4000DEBF0FBECDBF3C01B6E14B2E512C480E2C +:106E5000591EFC0164897589C20148D9C30108968D +:106E60009D838C83F301E45AFF4FFF83EE83C301BC +:106E7000C99699878887AFE72A2E312C260C371CB4 +:106E800000D000D00F92F3012089318942895389C3 +:106E900084859585A685B785EDB7FEB781839283F6 +:106EA000A383B483F3018385EDB7FEB785838C811B +:106EB0009D8164E08201EE80FF80C884D984510105 +:106EC000F30182842ADC9B838A830F900F900F90BA +:106ED0000F900F90009709F087C0C3018B539F4F0D +:106EE0009D878C87FC0140815181141615060CF09A +:106EF0009DC0E0E0F0E060E000E010E0E60DF71D8E +:106F0000E953FF4F8081882351F090E09C0121706C +:106F10003070020F131F959587958823B1F76F5F27 +:106F2000E62FF0E0E417F5074CF3CE01019636D1D9 +:106F3000222717FD2095322F095F1F4F2F4F3F4FFC +:106F4000E3E03595279517950795EA95D1F71F87C3 +:106F50000E879924C30188519F4F9B878A87F3012D +:106F6000EE55FF4FF98BE88B8981981608F043C0E6 +:106F70008A859B856E857F85B9D8C2016A857B85A8 +:106F8000488959892C853D85EBDE00D000D00F92D1 +:106F9000F301208931894289538984859585A685A5 +:106FA000B785EDB7FEB781839283A383B483F301E2 +:106FB0008385EDB7FEB785838C819D8164E0820176 +:106FC000EE80FF80C884D9845101F3018284A5DB5F +:106FD0000F900F900F900F900F90009739F49394AB +:106FE0008981981640F4C4CF8A819B81F3019783ED +:106FF00086839B838A838A819B8161960FB6F894EE +:10700000DEBF0FBECDBFCF91DF911F910F91FF90DB +:10701000EF90DF90CF90BF90AF909F908F907F9038 +:107020006F905F904F903F902F90089500E010E098 +:107030007CCFCF93DF93EC01188219821A821B82D6 +:107040001C821D821F821E821B86188681E0898712 +:107050008A87188A198A1A8A1B8A1D8A1C8A1C86A2 +:107060001D861E861F86CE01089660E04AD98E8353 +:107070009F83DF91CF910895CF93DF93EC012E8111 +:107080003F812115310519F48881882321F0C90138 +:10709000DF91CF910895CE01019680D08A819B81A6 +:1070A000AC81BD810196A11DB11D8A839B83AC83F8 +:1070B000BD83E981E83150F084E090E09F838E83C6 +:1070C00024E030E0C901DF91CF910895F0E0EE0FA8 +:1070D000FF1FE851FD4F0190F081E02DCE01099591 +:1070E0002E813F81D4CF0F931F93DF93CF93CDB7E2 +:1070F000DEB7CB50D1400FB6F894DEBF0FBECDBF88 +:107100008E010F5F1F4FC80194DF2F813885211535 +:10711000310569F0C901C55FDE4F0FB6F894DEBFD7 +:107120000FBECDBFCF91DF911F910F91089589813F +:10713000882381F7C801A0DF2F813885211531050B +:10714000B1F3E8CF8130910551F08230910561F0C3 +:10715000009721F46115710571F442980895611545 +:10716000710539F0439A08956115710531F0459A1A +:10717000089543980895429A08954598089580E0A7 +:1071800090E060E070E0DEDF80E090E061E070E0E1 +:10719000D9CF9093DC378093DB370895CF93DF937B +:1071A000EC01E091DB37F091DC37309729F009955D +:1071B0008883DF91CF9108951882DF91CF91089550 +:1071C00081E0349B80E00895AF92BF92CF92DF922E +:1071D000EF92FF920F931F935B016C011616170637 +:1071E0001806190674F4EE24FF248701C8DF0894FA +:1071F000E11CF11C011D111DEA14FB040C051D0509 +:10720000ACF31F910F91FF90EF90DF90CF90BF9064 +:10721000AF900895629FD001739FF001829FE00DAF +:10722000F11D649FE00DF11D929FF00D839FF00D05 +:10723000749FF00D659FF00D9927729FB00DE11DB1 +:10724000F91F639FB00DE11DF91FBD01CF0111248E +:107250000895AA1BBB1B51E107C0AA1FBB1FA6179D +:10726000B70710F0A61BB70B881F991F5A95A9F7EF +:1072700080959095BC01CD010895A1E21A2EAA1B1C +:10728000BB1BFD010DC0AA1FBB1FEE1FFF1FA217D6 +:10729000B307E407F50720F0A21BB30BE40BF50BD3 +:1072A000661F771F881F991F1A9469F7609570955C +:1072B000809590959B01AC01BD01CF01089597FB8E +:1072C000092E05260ED057FD04D0D7DF0AD0001CAA +:1072D00038F450954095309521953F4F4F4F5F4F73 +:1072E0000895F6F790958095709561957F4F8F4F33 +:1072F0009F4F08950790F691E02D099491110895FC +:1073000081568A5108F4805285580895FC010590F1 +:107310000020E9F7809590958E0F9F1F0895FB013F +:10732000DC0104C08D910190801921F4415050403E +:10733000C8F7881B990B0895FB01DC0102C001907E +:107340000D9241505040D8F70895FB01DC014150A7 +:10735000504030F08D910190801919F40020B9F758 +:10736000881B990B0895FB01DC014150504048F007 +:1073700001900D920020C9F701C01D92415050406C +:10738000E0F708950F931F93DF93CF93CDB7DEB748 +:107390002E970FB6F894DEBF0FBECDBF0D891E89A4 +:1073A0008F89988D26E02C831A83098397FF02C06A +:1073B00080E090E801979E838D839E01255E3F4F7C +:1073C000CE010196698D7A8DA90119D04D815E811A +:1073D00057FD0AC02F813885421753070CF49A01D4 +:1073E000020F131FF80110822E960FB6F894DEBF1D +:1073F0000FBECDBFCF91DF911F910F9108952F92B6 +:107400003F924F925F926F927F928F929F92AF9234 +:10741000BF92CF92DF92EF92FF920F931F93DF9371 +:10742000CF93CDB7DEB72C970FB6F894DEBF0FBE63 +:10743000CDBF6C011B018A01FC011782168283817A +:1074400081FFC4C12E010894411C511CF601938197 +:10745000F10193FD859193FF81911F01882309F428 +:10746000B1C1853239F493FD859193FF81911F015C +:10747000853221F490E0B601F5D1E8CFEE24FF2467 +:1074800020E02032B0F48B3269F08C3228F4803264 +:1074900051F0833271F40BC08D3239F0803349F4EE +:1074A00021602CC02260246029C0286027C0206190 +:1074B00025C027FD2CC0382F30533A3098F426FFD2 +:1074C00008C08E2D880FE82EEE0CEE0CE80EE30EB1 +:1074D00015C08F2D880FF82EFF0CFF0CF80EF30E41 +:1074E00020620CC08E3221F426FD6CC1206406C0DF +:1074F0008C3611F4206802C0883649F4F10193FDFE +:10750000859193FF81911F01882309F0BACF982FAD +:107510009554933018F09052933028F40C5F1F4F1D +:10752000FFE3F9830DC0833631F0833771F0833583 +:1075300009F05CC021C0F801808189830E5F1F4F74 +:10754000420171E0A72EB12C15C062E0662E712CAD +:10755000600E711EF8018080918026FF03C06E2DA1 +:1075600070E002C06FEF7FEFC4012C8770D15C0127 +:1075700083012C852F7716C052E0652E712C600E8A +:10758000711EF8018080918026FF03C06E2D70E08F +:1075900002C06FEF7FEFC4012C874ED15C012C85B8 +:1075A0002068830123FD1EC007C080E290E0B60181 +:1075B0002C8758D1FA942C858F2D90E0A816B90607 +:1075C000A0F310C0F40127FD859127FF81914F01A1 +:1075D00090E0B6012C8746D12C85F110FA940894DE +:1075E000A108B108A114B10469F7E9C0843611F00B +:1075F000893641F527FF08C0F801608171818281D9 +:1076000093810C5F1F4F09C0F80160817181882749 +:1076100077FD8095982F0E5F1F4F4FE6B42EB22254 +:1076200097FF09C090958095709561957F4F8F4F1A +:107630009F4FF0E8BF2AA2012AE030E03FD1782E28 +:10764000741844C0853731F43FEEB32EB2222AE0DD +:1076500030E025C099EFB92EB2228F36C1F08037C5 +:1076600020F4883509F0AEC00DC0803721F088378E +:1076700009F0A8C002C020E1B22AB4FE0BC084E029 +:10768000B82A08C0B4FE09C0E6E0BE2A06C028E059 +:1076900030E005C020E130E002C020E132E0B7FE7A +:1076A00008C0F80160817181828193810C5F1F4F56 +:1076B00007C0F8016081718180E090E00E5F1F4F8C +:1076C000A201FCD0782E7418FFE7BF22B6FE0BC0D3 +:1076D0002EEFB2227E1438F4B4FE07C0B2FC05C00F +:1076E0008FEEB82202C0A72C01C0AE2C8B2D90E0EB +:1076F000B4FE0DC0FE01E70DF11D2081203319F409 +:10770000E9EEBE2209C0A394B2FE06C004C086788A +:107710009070009709F0A3948B2C9924B3FC13C0AC +:10772000B0FE0EC0AF1428F4E72CEF0CEA18AF2C13 +:1077300007C0E72C05C080E290E0B60193D0A39487 +:10774000AF14C8F304C0AF1410F4FA1801C0FF243A +:1077500084FE0EC080E390E0B60184D082FE1DC09E +:1077600081FE03C088E590E010C088E790E00DC07E +:10777000C40186789070009781F081FC02C080E29D +:1077800001C08BE2B7FC8DE290E0B6016BD005C082 +:1077900080E390E0B60166D0EA947E14C8F37A9450 +:1077A000F201E70DF11D808190E0B6015BD07720FA +:1077B000B1F705C080E290E0B60154D0FA94FF2002 +:1077C000C9F744CEF6012681378102C02FEF3FEF83 +:1077D000C9012C960FB6F894DEBF0FBECDBFCF9176 +:1077E000DF911F910F91FF90EF90DF90CF90BF90AE +:1077F000AF909F908F907F906F905F904F903F9051 +:107800002F900895F999FECF92BD81BDF89A9927DE +:1078100080B50895262FF999FECF92BD81BDF89AC3 +:10782000019700B4021639F01FBA20BD0FB6F894C4 +:10783000FA9AF99A0FBE0895FC01059061507040C4 +:107840000110D8F7809590958E0F9F1F0895FC0129 +:107850006150704001900110D8F7809590958E0F7F +:107860009F1F08950F931F93CF93DF938C01EB011C +:107870008B8181FF1BC082FF0DC02E813F818C81D7 +:107880009D812817390764F4E881F9810193F98310 +:10789000E88306C0E885F985802F0995009731F4C3 +:1078A0008E819F8101969F838E8302C00FEF1FEF11 +:1078B000C801DF91CF911F910F910895FA01AA2776 +:1078C000283051F1203181F1E8946F936E7F6E5F23 +:1078D0007F4F8F4F9F4FAF4FB1E03ED0B4E03CD0D1 +:1078E000670F781F891F9A1FA11D680F791F8A1FB4 +:1078F000911DA11D6A0F711D811D911DA11D20D01B +:1079000009F468943F912AE0269F11243019305DD4 +:107910003193DEF6CF010895462F4770405D4193C5 +:10792000B3E00FD0C9F7F6CF462F4F70405D4A3312 +:1079300018F0495D31FD4052419302D0A9F7EACFDA +:10794000B4E0A6959795879577956795BA95C9F709 +:1079500000976105710508959B01AC010A2E0694FC +:107960005795479537952795BA95C9F7620F731FB5 +:10797000841F951FA01D089517E000E0C4E6D7E01E +:1079800040E005C022974109FE014BBFB3DCC6367B +:0A799000D1074007B9F7F894FFCFC4 +:10799A002E2E0053656C656374204469736B006E08 +:1079AA006F20696D6167652066696C657320666F13 +:1079BA00756E640001030507090E10121416181CCF +:1079CA001E696E636F6D706C657465207772697479 +:1079DA00650062616420736563746F722025642098 +:1079EA00666F722074256400627566206C6F636B23 +:1079FA0065642025642F25643A25640063686563FD +:107A0A006B73756D206661696C75726520300063F1 +:107A1A006865636B73756D206661696C7572652044 +:107A2A003100636865636B73756D206661696C7597 +:107A3A007265203200636865636B73756D206661D9 +:107A4A00696C0043504C44204669726D77617265D7 +:107A5A00202564002564002575006669726D7761CA +:107A6A0072652E78766600534420726561642065DB +:107A7A0072726F72205200526573756C743A207379 +:107A8A0075636365737300526573756C743A206528 +:107A9A0072726F72202564005344207265616420FB +:107AAA007374617274206572726F7200534420722B +:107ABA00656164206572726F722044007772207764 +:107ACA00726F6E6720747261636B2025642F256460 +:107ADA000052657665727465642074726B20253075 +:107AEA00326420202000534420726561642065724C +:107AFA00726F722057005344207772697465537409 +:107B0A00617274206661696C0053442077726974EB +:107B1A0065206572726F72005344207772697465CA +:107B2A0053746F70206661696C00536176656420D6 +:107B3A0074726B202530326420696E20256C7520A2 +:107B4A00200053442063617264206572726F722050 +:107B5A0025643A256400253032640025642000D566 +:107B6A00AAAD0000000000000000000000008A0129 +:107B7A00AD01D8010D024E02A2301B311D35713400 +:107B8A0024319A309A3003313D316236083109374F +:107B9A001C361C361C36D035D035D035D332C830D9 +:087BAA00C830C234A830993242 +:020000021000EC +:08EFF800DDDDDDDD000100009C +:00000001FF diff --git a/source-1.0L-F11/firmware/merged.hex b/source-1.0L-F11/firmware/merged.hex new file mode 100755 index 0000000..307ebb6 --- /dev/null +++ b/source-1.0L-F11/firmware/merged.hex @@ -0,0 +1,1123 @@ +:020000040000FA +:20000000B2C30000DFC30000DDC30000DBC300000C941F0ED7C300000C94AB0A0C94F7092F +:20002000D1C30000CFC30000CDC30000CBC30000C9C30000C7C30000C5C30000C3C3000058 +:20004000C1C30000BFC300000C945A1DBBC30000B9C30000B7C30000B5C30000B3C3000021 +:20006000B1C30000AFC30000ADC30000ABC30000A9C30000A7C30000A5C30000A3C3000018 +:20008000A1C300009FC300009DC3000000000C001800240030003C004800540060006C001E +:2000A0007800840090009C00A800B400C000CB00D600E100EC00F70002010D011801230149 +:2000C0002E01390144014F015A01650170017A0184018E019801A201AC01B601C001CA0135 +:2000E000D401DE01E801F201FC0106021002190222022B0234023D0246024F025802610222 +:200100006A0273027C0285028E029702A002A802B002B802C002C802D002D802E002E80214 +:20012000F002F80200030803100318030C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0B0B0B0BAB +:200140000B0B0B0B0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0909090957 +:200160000909090909090909090909090808080808080808080808080808080896979A9B31 +:200180009D9E9FA6A7ABACADAEAFB2B3B4B5B6B7B9BABBBCBDBEBFCBCDCECFD3D6D7D9DA10 +:2001A000DBDCDDDEDFE5E6E7E9EAEBECEDEEEFF2F3F4F5F6F7F9FAFBFCFDFEFF0001FFFF2A +:2001C0000203FF040506FFFFFFFFFFFF0708FFFFFF090A0B0C0DFFFF0E0F10111213FF145B +:2001E00015161718191AFFFFFFFFFFFFFFFFFFFFFF1BFF1C1D1EFFFFFF1FFFFF2021FF2290 +:20020000232425262728FFFFFFFFFF292A2BFF2C2D2E2F303132FFFF333435363738FF39C5 +:200220003A3B3C3D3E3F00002110422063308440A550C660E770088129914AA16BB18CC160 +:20024000ADD1CEE1EFF13112100273325222B5529442F772D662399318837BB35AA3BDD383 +:200260009CC3FFF3DEE36224433420040114E664C774A44485546AA54BB528850995EEE5C3 +:20028000CFF5ACC58DD55336722611163006D776F6669556B4465BB77AA719973887DFF743 +:2002A000FEE79DD7BCC7C448E5588668A7784008611802282338CCC9EDD98EE9AFF948897B +:2002C00069990AA92BB9F55AD44AB77A966A711A500A333A122AFDDBDCCBBFFB9EEB799B83 +:2002E000588B3BBB1AABA66C877CE44CC55C222C033C600C411CAEED8FFDECCDCDDD2AAD43 +:200300000BBD688D499D977EB66ED55EF44E133E322E511E700E9FFFBEEFDDDFFCCF1BBF42 +:200320003AAF599F788F8891A981CAB1EBA10CD12DC14EF16FE18010A100C230E3200450B7 +:20034000254046706760B9839893FBA3DAB33DC31CD37FE35EF3B1029012F322D2323542A2 +:20036000145277625672EAB5CBA5A89589856EF54FE52CD50DC5E234C324A01481046674A2 +:20038000476424540544DBA7FAB79987B8975FE77EF71DC73CD7D326F2369106B016576662 +:2003A0007676154634564CD96DC90EF92FE9C899E9898AB9ABA94458654806782768C0185A +:2003C000E1088238A3287DCB5CDB3FEB1EFBF98BD89BBBAB9ABB754A545A376A167AF10AA2 +:2003E000D01AB32A923A2EFD0FED6CDD4DCDAABD8BADE89DC98D267C076C645C454CA23C22 +:20040000832CE01CC10C1FEF3EFF5DCF7CDF9BAFBABFD98FF89F176E367E554E745E932E61 +:20042000B23ED10EF01E202020202020202020202020202020202020202020002049646C06 +:200440006500205265616400577269746500547261636B20202020536964650031343430CD +:200460004B204469736B436F707920696D616765003830304B204469736B436F7079206916 +:200480006D616765003430304B204469736B436F707920696D61676500313434304B2072D4 +:2004A000617720696D616765003830304B2072617720696D616765003430304B2072617788 +:2004C00020696D61676500696D616765206E6F7420636F6E746967756F7573006572726F5D +:2004E00072206F70656E696E6720696D61676500505245563A2043616E63656C004E45588F +:20050000543A204C6F6164206669726D7761726500626567696E0052656C656173652062E8 +:200520007574746F6E7320746F0043504C44204649524D5741524520555044415445004345 +:200540006F6E74726173743A200053454C4543543A2053617665004E4558543A20446172DD +:200560006B657200505245563A204C69676874657200626567696E0052656C6561736520ED +:20058000627574746F6E7320746F00434F4E54524153542041444A5553544D454E5400417B +:2005A00070702056657273696F6E20312E30204C002020202020464C4F50505920454D55B9 +:2005C00020202020202000507265737320616E7920627574746F6E006669726D77617265CD +:2005E0002E78766600436F756C64206E6F74206F70656E005570646174696E6720666972A2 +:200600006D776172652E2E2E00464154414C204552524F522020202020202020202000578B +:2006200052495445204552524F5220202020202020202020000000000017000300031F0A56 +:200640001F0A1F050904120F171C000303000E11110E00050205040E041008000404040062 +:2006600010001804031E110F021F0019151215150A07041F1715091E151D1905031A150B6E +:2006800017150F000A00040C04040E1F0A0A0A1F0E040115030E15161E051E1F150A0E1191 +:2006A000111F110E1F15151F05050E151D1F041F111F1108100F1F041B1F10101F061F1FAF +:2006C0000E1F0E110E1F05020E191E1F0D16121509011F010F101F0718071F0C1F1B041BDA +:2006E000031C031915131F101002040810101F0406041010100003031A161C1F120C0C1220 +:20070000120C121F0C1A16041E050C2A1E1F021C001D0010201D1F0C12111F101E0E1E1E47 +:20072000021C0C120C3E120C0C123E1C0202141E0A021F120E101E0E180E1E1C1E120C1232 +:2007400006281E1A1F16041B11001F00111B04080C047C3C3E5E2B3D3F2F5B5D3B2C2A22D2 +:200760005C00451D491D11241FBECFEFD0E4DEBFCDBF13E0A0E0B1E0EAE9F9E700E00BBF47 +:2007800002C007900D92A831B107D9F717E3A8E1B3E001C01D92AD3DB107E1F717E000E029 +:2007A000C4E6D7E040E006C022974109FE014BBF0E947A39C236D1074007B1F70E941918FF +:2007C0000C94BC3C1DCC2F923F924F925F926F927F928F929F92AF92BF92CF92DF92EF92EB +:2007E000FF920F931F93DF93CF93CDB7DEB72D970FB6F894DEBF0FBECDBF8B014A013E0106 +:200800000894611C711CD301E4E2F1E02DE001900D922150E1F7BB244424AA2452E8552E6F +:2008200042E2E42EF12CE80EF91E3EE0C32ED12CCC0EDD1E22E8222E312C280C391CC7016F +:20084000B80140E250E00E94C92480329105A1F4D8011B968C911B9790E09C012F73307079 +:200860002F30310559F183FD23C0F8018081853E19F1882309F05AC0D4011C9280E02D960B +:200880000FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F9058 +:2008A0008F907F906F905F904F903F902F900895F8018081882301F3BB24C1CFBB2021F519 +:2008C0008C91982F907E903409F0B9CF9FE1A92EA8221D964C90F1011082A5E7B0E085E725 +:2008E000582EF301AD01480D591D81919801280F311DD9018C91DA018D93AD01EC15FD0532 +:20090000A1F7BB24B3949BCFD8018C91AA948A1599F61D968C911D97841571F6552009F457 +:200920008ECFB3EF5B0EA52DB0E0DBCF8E3221F2BB2081F031962BE090E001C08191392FA7 +:200940003795332737959695932B980F2150B1F7941531F0C801B4010E94092481E08FCF26 +:20096000FA2DF130B9F7452D50E043385105B4F79A0160E080E090E0880D991D280D391DE0 +:20098000D9012C91FC0120836F5F862F90E09C01240F351F233831057CF381E070CFEF92E8 +:2009A000FF920F931F93DF93CF93CDB7DEB7A9970FB6F894DEBF0FBECDBFFC01DB018C91E8 +:2009C0008E32A9F1838590E0887190708031910509F466C0009759F5848D958DA68DB78D53 +:2009E000803020E4920726E0A20720E0B20709F459C0803020E892072CE0A20720E0B2076D +:200A000009F454C0803020E8920726E1A20720E0B20709F449C081509044A640B0408F3FBC +:200A20002FE2920721E1A20720E0B20778F020E0822FA9960FB6F894DEBF0FBECDBFCF91A9 +:200A4000DF911F910F91FF90EF900895CF017E010894E11CF11CB7010E9409241E86198A68 +:200A60008E01025F1F4FC801B70141E00E94342A882371F0C80165E773E340E052E00E940B +:200A8000C924C8010E9433278091C733813081F08989882361F2C8010E94332720E0C8CF0B +:200AA00021E0C6CF23E0C4CF25E0C2CF24E0C0CF8091C833882361F78091B63390E0A0E0E8 +:200AC000B0E0BA2FA92F982F88272091B733820F911DA11DB11DB695A79597958795B695CF +:200AE000A79597958795803921E0920720E0A20720E0B207F1F0803223E0920720E0A207E5 +:200B000020E0B207A1F0803A25E0920720E0A20720E0B20709F0BCCF28E08989882309F48B +:200B200087CFC80129A70E94332729A581CF27E0F4CF26E0F2CF2F923F924F925F926F92B6 +:200B40007F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7C05F5C +:200B6000D0400FB6F894DEBF0FBECDBF7C011092190310921803829640E050E0BA010E9461 +:200B80004B2603E4C02ED12CCC0EDD1E13E6A12EB12CAC0EBD1EB4E26B2E712CC701B601B8 +:200BA000A50111DE8823E1F1809118039091190321E08734920708F0A7C1C601B501EFDEBB +:200BC000882E882359F38091180390911903869D8001879D100D969D100D11240B581C4FC7 +:200BE000C801B50146E150E00E94B339B8016A5E7F4FC6010E940924809118039091190343 +:200C0000869DF001879DF00D969DF00D1124EB58FC4F83A201969093190380931803BECFF6 +:200C20002091180330911903C751DF4F39832883C95ED040F70185A182508230A8F184E286 +:200C400090E0C751DF4FE881F981C95ED040E89F8001E99F100DF89F100D11240B581C4F60 +:200C6000C80160E071E046E150E00E94B339C801469660E071E04DE050E00E94B33982E0B2 +:200C8000F80183A3C751DF4F28813981C95ED0402F5F3F4FC751DF4F39832883C95ED04055 +:200CA0003093190320931803A8E92A2EA3E03A2E80E090E07E010894E11CF11CF7E1CF2EE9 +:200CC000D12CCC0EDD1EC751DF4FE881F981C95ED0408E179F0708F01EC1FC013196C351E8 +:200CE000DF4FF983E883CD5ED040C751DF4F28813981C95ED040E217F30708F026C1C10130 +:200D00008397F101B496C151DF4FF983E883CF5ED0405F01C351DF4F48805980CD5ED0409B +:200D2000CA51DF4F8883C65ED04091012D503040C551DF4F39832883CB5ED040C951DF4F80 +:200D400039822882C75ED040392EC701CA51DF4F6881C65ED040732D46E150E00E94B339DF +:200D600088240AC00E0D1F1DF801808190E00E947E39F80180838394F70101900020E9F747 +:200D80003197EE19FF09082D10E00E171F0750F3EDED8E2EEFEF9E2E8A0C9B1C682C292C53 +:200DA000C601B40146E150E00E94B33977240AC00C0D1D1DF801808190E00E947E39F8015E +:200DC00080837394F60101900020E9F73197EC19FD09072D10E00E171F0750F3C701B6017D +:200DE00046E150E00E94A539282F392FC951DF4FE881F981C75ED04080818150823008F47D +:200E000080C0F50180818150823008F477C0121613060CF055C0CE018D96CA51DF4F68816F +:200E2000C65ED040732D46E150E00E94B339CA51DF4F8881C65ED040932D662D722D46E15A +:200E400050E00E94B339862D922DBE01635D7F4F46E150E00E94B339CE018D96C551DF4FFA +:200E600068817981CB5ED0404DE050E00E94B33984010A5E1F4FC551DF4F88819981CB5E80 +:200E8000D040B8014DE050E00E94B339C801BE01635D7F4F4DE050E00E94B339C951DF4F55 +:200EA000E881F981C75ED0408081F5019081C951DF4FE881F981C75ED0409083F5018083A6 +:200EC0000894411C511C24E230E0A20EB31EC751DF4F88819981C95ED0404816590608F4BC +:200EE00034CFC151DF4F28803980CF5ED040C351DF4F88819981CD5ED040E5CE28513C4FBA +:200F000086CF285E33407DCFC751DF4F99838883C95ED0408FCEC051DF4F0FB6F894DEBF09 +:200F20000FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F9072 +:200F40005F904F903F902F900895C1018496C151DF4F99838883CF5ED040C3CF8F929F9234 +:200F6000AF92BF92CF92DF92EF92FF920F931F93CF93DF9380911A0390911B0320911C0396 +:200F800030911D032817390728F430931B0320931A03C90104968217930730F42450304085 +:200FA00030931B0320931A0380E060E00E949A1D81E06FE70E948B1DC3E1D0E081E060E48D +:200FC0000E948B1D2197D1F783E091E00E948F1EC3E1D0E081E060E40E948B1D2197D1F761 +:200FE00081E06FE70E948B1D20911803309119032115310509F464C140911A0350911B03CC +:20100000CA0105964817590708F033C14217530708F02FC164E270E0469F7001479FF00C56 +:20102000569FF00C112488E993E0E80EF91EEA0191E0C92ED12CBB24B39480911C039091D2 +:201040001D03C817D90709F0BB24AC2C80E06C2D0E949A1D04E510E007C060E081E00E94CC +:201060008B1D0150104049F0BB20B9F36FE781E00E948B1D01501040B9F781E06A2D0E947B +:201080009A1D870103521040902E812EC8016B2D43E50E94A61DF70180818150823008F499 +:2010A000BDC0BB2009F0A4C08601219640911A0350911B03CA010596C817D907E0F12091A9 +:2010C0001803309119032630310508F047C0EE24E39482E56E2D0E949A1D81E060E00E9466 +:2010E0008B1D81E060E00E948B1DE3947E2D763081F780911A0390911B039801280F391F88 +:2011000040911C0350911D034217530708F4E2C02150304030931D0320931C0304301105AD +:2011200009F02CCF009709F429CF019790931B0380931A0323CF20911803309119030894EF +:20114000C11CD11C64E270E0E60EF71EC217D30708F471CF2630310508F4B9CFE7E2F0E08E +:201160004E9FC0014F9F900D5E9F900D11248D539F4FB9010E94293988E0E82EE60E83ECFA +:2011800090E0B9010E942939CE2CC61AC8E0D0E0BB24B39482E56B2D0E949A1D81E060E0D0 +:2011A0000E948B1D4C2F9E01295F3F4F2C173D070CF484C060E00AC0E41650F066956068E3 +:2011C0004F5F842F90E0281739074CF04C15A0F766954F5F842F90E028173907BCF781E02C +:2011E0000E948B1DB39428967B2D763099F681CF84E393E0692D782D46E150E00E94B33979 +:20120000B8016A5E7F4F8EE193E04DE050E00E94B339F701808180934A0346CF89E46A2D40 +:201220000E949A1DBB2041F181E06FE70E948B1D81E063E40E948B1D81E06DE50E948B1D58 +:2012400081E06DE50E948B1D81E06DE50E948B1D81E06BE50E948B1D81E06BE50E948B1D9E +:2012600081E063E40E948B1D6FE781E00E948B1D18CF00E010E027CF81E060E00E948B1DE3 +:2012800081E06CE30E948B1D81E062E20E948B1D81E062E20E948B1D81E062E20E948B1D87 +:2012A00081E064E20E948B1D81E064E20E948B1D81E06CE30E948B1D60E0D7CF60E08FCFCE +:2012C00080E061E00E949A1D8FE091E060E044E50E94A61DDF91CF911F910F91FF90EF9038 +:2012E000DF90CF90BF90AF909F908F9008958130910559F0009721F48091A135882309F4DC +:2013000008958EE995E30C94332710929E351092A13508958FE781B9559A209A3A9A3D9AB9 +:201320003E9A3B9A239A5C9A599A5A9A5F9A5B9A179A589A409A419A289A429A45984698C7 +:20134000439A2B9AE3E7F0E0808181608083EDE6F0E0808182608083808181608083089561 +:201360001F93DF93CF93CDB7DEB72A970FB6F894DEBF0FBECDBFCE010196DC01EEEDF2E0D6 +:201380002AE001900D922150E1F7E0914C03F0E0F595E795F595E795F595E795F595E79522 +:2013A0001FB7F894E53008F0E4E0F0E0EE0FFF1FE80FF91F20813181220F331F40E050E0DA +:2013C00060E07DE281E391E00E945F3930935B0320935A031FBF82E086BB2A960FB6F8949C +:2013E000DEBF0FBECDBFCF91DF911F9108951F920F920FB60F920BB60F9211242F933F93F7 +:201400004F935F936F937F938F939F93AF93BF93CF93DF93EF93FF93489B2FC0E0914C0382 +:2014200080915503882309F03DC0F0E0E45DFE4F249130E0220F331F21153105A9F5379922 +:201440005DC080914C038F5F80934C0380914C03882309F064C04598429A4899FECF429856 +:20146000459A7EDFC0919435D0919535C330D10508F057C081E080935103FF91EF91DF91CB +:20148000CF91BF91AF919F918F917F916F915F914F913F912F910F900BBE0F900FBE0F9029 +:2014A0001F90189524E230E080E090E040E050E068E188589A4CFC01808180FF03C06831B2 +:2014C00059F1542F4F5F842F90E0821793070CF1561708F4B4CF862FE82FF0E0E858FA4C30 +:2014E000908191FF03C09081916090839081946090838F5F581780F7379BA3CF80914C03E3 +:20150000882309F4A3CF80914C03815080934C039DCF4831E9F2CDCF542F642FD3CF459A2B +:201520009BCF8FE593E061E371E046E150E00E94B339C851DC4FD0937735C09376351092ED +:20154000500381E0809351038093520310929535109294358FCF1F920F920FB60F920BB65A +:201560000F9211241F932F933F934F935F936F937F938F939F93AF93BF93CF93DF93EF9329 +:20158000FF9386B190E095958795817090914E03891791F090915803923009F46DC010923E +:2015A0004E0311E010935103C0919435D0919535C330D10508F047C086B1817011E0812724 +:2015C000909150038917C9F08093500380915003882349F58FE781B9469880916B008F777B +:2015E00080936B00C0919435D0919535C330D10508F045C081E080935103FF91EF91DF911A +:20160000CF91BF91AF919F918F917F916F915F914F913F912F911F910F900BBE0F900FBE96 +:201620000F901F90189511B8469A80916B00806880936B0080B180788093933510929535B4 +:2016400010929435D7CF8FE593E061E371E046E150E00E94B339C053D84FD0937735C0937C +:2016600076351092500310935103109352031092953510929435A0CF80934E0392CF8FE55C +:2016800093E061E371E046E150E00E94B339C854D44FD0937735C093763510925003109379 +:2016A0005103109352031092953510929435A2CF1F93E0B1E0688091943590919535843092 +:2016C000910588F48330910509F487C0DC01A153BD4F2C912E1709F404C1109295351092BC +:2016E00094351F910895F0E0EA5DFE4FE49132E08F3B930748F59C012370307022303105F0 +:2017000009F4BBC02330310509F449C12130310509F418C1EE0FEE0FE093963540919A358C +:2017200050E09A01220F232F221F330B20939B35440F551F422B40939A35019690939535FF +:20174000809394351F910895F2E08F3B9F0709F4C1C022E0803C920709F4CEC032E0813CEF +:20176000930709F4E2C1F2E0823C9F0709F0B5CF80919635982F990F990F90939635E82B88 +:2017800090919A35E917C9F08FE593E062E971E046E150E00E94B33980E490E09093773595 +:2017A000809376351092500381E080935103809352031092953510929435E0919735F0E062 +:2017C000E858FA4C80818260808380818160808380818B7F80832B9A80CFF0E0EA5DFE4F32 +:2017E0001491E0914C0380915503882309F082C0F0E0E45DFE4FE4911E1708F04DC1E091B6 +:201800004C03882309F074C0F0E0E45DFE4FE49180914E03E89F802D1124810F8093973594 +:2018200090E0DC01A858BA4C2C9122FDE0C0982F8827990F8B589C4F90939D3580939C3514 +:201840008C9184608C938C918D7F8C9380914C038093903580914E03809391351093923543 +:201860002B9810929A3510929935109298358091943590919535019661CF50919635452FA9 +:20188000407C4E2B2091983542278431910578F0E0919C35F0919D354193F0939D35E09348 +:2018A0009C3550919635809194359091953560919B352091993530E0260F311D240F311D92 +:2018C0002093993530939B35550F550F50939635019634CFEE0FEE0FE093963580EC92E0CE +:2018E0002DCF20915403222309F0F7CE019626CFE2E18ECFE2E180CF80919635982F990FD8 +:20190000990F90939635807C8E2B90919835891709F46AC08FE593E06CE671E046E150E0E6 +:201920000E94B3398EE390E090937735809376351092500381E0809351038093520381E025 +:2019400090E0FCCE50919635452F407C4E2B20919A3542278431910578F0E0919C35F09199 +:201960009D354193F0939D35E0939C3550919635809194359091953560919B352091983578 +:2019800030E0260F311D240F311D2093983530939B35550F550F509396350196CFCE4091A5 +:2019A00096354E2B2091993542278431910568F0E0919C35F0919D354193F0939D35E09327 +:2019C0009C35809194359091953550919B3520919A3530E0250F311D240F311D20939A35AB +:2019E00030939B350196AACE81EC92E0A7CE30914C0320914E038DB79EB70C970FB6F89452 +:201A00009EBF0FBE8DBFADB7BEB711968FE593E0EDB7FEB79283818386E190E013969C93C8 +:201A20008E93129788E591E015969C938E93149716963C93169717961C92179718962C93BA +:201A4000189719961C9219971A961C931A971B961C920E94C2398DE390E0909377358093FC +:201A600076351092500381E0809351038093520310929535109294358091973590E02DB78E +:201A80003EB7245F3F4F0FB6F8943EBF0FBE2DBFDC01A858BA4CCBCE20914C038DB79EB724 +:201AA0000A970FB6F8949EBF0FBE8DBFADB7BEB711968FE593E0EDB7FEB79283818386E17E +:201AC00090E013969C938E93129782E491E015969C938E93149716961C93169717961C9214 +:201AE000179718962C93189719961C920E94C2398CE390E0909377358093763510925003C1 +:201B000081E080935103809352031092953510929435809155032DB73EB7265F3F4F0FB6A4 +:201B2000F8943EBF0FBE2DBF6ACE80919635982F990F990F90939635807C8E2B90919935A6 +:201B4000891759F08FE593E06FE771E046E150E00E94B3398FE390E0E7CE82EC92E0EECDF7 +:201B60004091560350915703E2EEF2E02591349160E07FEF2627372791EA692F632770E09D +:201B8000660F771F6A5D7D4FFB0165917491322F2227262737279327E92FF0E0EE0FFF1F9E +:201BA000EA5DFD4F65917491322F222726273727EBEFE327F0E0EE0FFF1FEA5DFD4F6591EA +:201BC0007491322F222726273727B82FBB0FA0E0AB58BC4F80E090E0722F6627ED91E327E6 +:201BE000F0E0EE0FFF1FEA5DFD4F2591349126273727019662E08030960771F73093570396 +:201C00002093560342175307C9F08FE593E065EA71E046E150E00E94B33986E490E09093E3 +:201C20007735809376351092500381E08093510380935203109295351092943508951F92F0 +:201C40000F920FB60F920BB60F9211242F933F934F935F936F937F938F939F93AF93BF9382 +:201C6000EF93FF9390B180915003882309F456C0892F807890919335891709F44FC0809395 +:201C8000933590915503992309F46FC0882309F461C020B12F7080919635282B2093963535 +:201CA00080919435909195358230910509F45FC0009709F446C08130910509F46DC032E0DE +:201CC0008330930708F458C0A2E083309A0709F49AC0B2E084309B0709F530E08091560316 +:201CE00090915703822B932B90935703809356038091973535DFE0919735F0E0E858FA4C91 +:201D000080818260808380818160808380818B7F80832B9A1092953510929435FF91EF913E +:201D2000BF91AF919F918F917F916F915F914F913F912F910F900BBE0F900FBE0F901F9031 +:201D40001895213A59F781E090E09093953580939435E4CF80B190E082959295907F982731 +:201D6000807F982780939635D9CFA2DCD7CF2B3FE9F0213A79F6D2CF30919735F32FFF0F90 +:201D8000E0E0E80FF91FEE58FC4F208301969093953580939435C2CF213A09F0BBCF82E00F +:201DA00090E09093953580939435B8CF83E090E0909395358093943520915903209397353B +:201DC000822F90E0FC01E858FA4C308132FD26C0982F8827990F8B589C4F90939D358093A5 +:201DE0009C3580818460808380818D7F808380914C038093903580914E03809391352093F4 +:201E000092352B988BCF109256032093570384E092E0909395358093943580CF50914C03B8 +:201E200040914E032DB73EB72C5030400FB6F8943EBF0FBE2DBFEDB7FEB731962FE533E06D +:201E4000ADB7BEB712963C932E93119726E130E03383228328E531E0358324835683178268 +:201E600040871186938782870E94C23987E490E090937735809376351092500381E0809373 +:201E800051038093520310929535109294352DB73EB7245F3F4F0FB6F8943EBF0FBE2DBFBE +:201EA0003DCFF89490915003992341F48F7782B9459A079BFECF0799FECF459878940895A3 +:201EC0008AE082B9459A079BFECF0799FECF4598E091570381EAE827F0E0EE0FFF1FEA5D4E +:201EE000FD4F859194913091560320E082279327909357038093560381E182B9459A079BD7 +:201F0000FECF0799FECF45980895982F92959F7092B9459A079BFECF0799FECF4598482FB6 +:201F20004F70E0915703E827F0E0EE0FFF1FEA5DFD4F859194913091560320E082279327D2 +:201F4000909357038093560342B9459A079BFECF0799FECF459808952F923F924F925F9204 +:201F60006F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF9300D00F92EE +:201F8000CDB7DEB78983692EA2EDCA2EA2E0DA2E992422243324EE24FF2400E010E088C0CD +:201FA0001070C801880F991F2801440C452C441C55085194482A592AF6010191852D99270D +:201FC000820D931D800F911DAFEF4A225524D6011196AC906F010894C11CD11CA7014A0D73 +:201FE000511D9C0120703170232F3327420F531F3FEF232E312C2822392271802FEFE22E96 +:20200000F12CE422F522872C8E24042510E0A224BB24F501E07CF070F595E795F595E795A5 +:20202000F595E795F595E7959801207C30703595279535952795E22BF32B882D82958695A1 +:202040008695837090E0E82BF92BE458FE4F84914A835B8326DF0F73107004581E4FF801B9 +:2020600084911FDF809151034A815B81882309F0A9C00894C11CD11C8201070D111D407059 +:202080005170452F5527040F151FF501EF73F070E458FE4F849105DFE82DF0E0EF73F07067 +:2020A000E458FE4F8491FDDE9394F92DFE3A41F0292D243009F074CF9981C92ED62C70CFB9 +:2020C0001070C801880F991F5801AA0CAB2CAA1CBB08B194A82AB92AD6010C91200E311C10 +:2020E0008B2D9927280E391E1196CC90EC0CF11CC10180709170892F9927E80EF91E0A256C +:2021000010E0C224DD24F601E07CF070F595E795F595E795F595E795F595E795C801807C58 +:2021200090709595879595958795E82BF92BE458FE4F8491B6DEF801EF73F070E458FE4F66 +:202140008491AFDEF601EF73F070E458FE4F8491A8DEF101E07CF070F695E795F695E79544 +:20216000C501807C90700024880F991F001C880F991F001C892F902DE82BF92BC701807C33 +:202180009070929582958F7089279F708927E82BF92BE458FE4F849184DEF101EF73F070A8 +:2021A000E458FE4F84917DDEF701EF73F070E458FE4F849176DEF501EF73F070E458FE4F39 +:2021C00084916FDE0F900F900F90CF91DF911F910F91FF90EF90DF90CF90BF90AF909F9007 +:2021E0008F907F906F905F904F903F902F900895CF93DF9380E060E00E949A1D81EB95E00B +:2022000061E00E94271E8FE995E00E9486398195880F865D62E00E949A1D8FE995E060E0F0 +:202220000E94271E4DB75EB7485050400FB6F8945EBF0FBE4DBFEDB7FEB73196CFE5D3E0A8 +:20224000ADB7BEB71296DC93CE93119786E190E09383828383EB91E09583848380915E0323 +:20226000868317820E94C239FE0101900020E9F73197EC1BFD0B4DB75EB7485F5F4F0FB685 +:20228000F8945EBF0FBE4DBF8E2F8195880F865D63E00E949A1DCE0160E044E50E94A61D36 +:2022A0002B980E94531D95E028E04FEF53ED60E3415050406040E1F700C0000085B18227D3 +:2022C00085B9915091F70E94571DDF91CF910895CF92DF92EF92FF920F931F93DF93CF93C8 +:2022E00000D000D0CDB7DEB780E060E00E949A1D0E94D21E80E060E00E949A1D8BE895E0B9 +:2023000060E00E94271E80E062E00E949A1D88E795E060E00E94271E80E063E00E949A1D94 +:2023200082E795E060E00E94271E499BFECF4A9BFCCF4C9BFACF80E060E00E949A1D0E94EC +:20234000D21E80E062E00E949A1D84E695E060E00E94271E80E063E00E949A1D87E595E0AF +:2023600060E00E94271E80E064E00E949A1D8AE495E060E00E94271E8E010F5F1F4F84EC54 +:20238000E82E81E0F82EB4E0CB2ED12C16C08091C7358F3F29F08091C7358F5F8093C73542 +:2023A00080E061E20E948B1D6091C73580E00E948B1D80E060E20E948B1D80E060E00E946B +:2023C0009A1D8FE395E060E00E94271E8091C7352DB73EB7285030400FB6F8943EBF0FBE4F +:2023E0002DBFEDB7FEB73196ADB7BEB712961C930E931197D382C282F582E4828683178240 +:202400000E94C2392DB73EB7285F3F4F0FB6F8943EBF0FBE2DBFC80160E044E50E94A61D93 +:202420008FEF99E6A8E181509040A040E1F700C00000499B04C04A9B02C04C99FACF4A9B1B +:20244000A6CF49990BC08091C735813808F4A8CF8091C73581508093C735A2CF4C99A0CF6F +:202460006091C73581E090E00E940A3C0F900F900F900F90CF91DF911F910F91FF90EF900C +:20248000DF90CF9008951F930E94D21E80E060E00E949A1D84E393E060E044E50E94A61DEC +:2024A00080E061E00E949A1D8EE995E36EE173E043E00E94342A882309F48AC080914A031E +:2024C000833029F1863019F182E0809358038EE995E36BEB75E34FEB55E30E9456238823CA +:2024E000D1F487EC94E060E00E94271E8FEF93E2A4EF81509040A040E1F700C0000010E07A +:202500008EE995E30E943327812F1F91089581E080935803DCCF80E061E00E949A1D80914E +:202520004A03853009F4BFC0863008F05FC0833009F4A1C0843039F489EA94E060E00E9495 +:20254000271E80914A0391E0863008F490E0909375354F998CC0992309F45CC081E08093FB +:20256000540348E754E060E070E08EE995E30E944B268EE995E365E773E040E052E00E948D +:20258000C924E0917503F0E0EA58FC4F108210928B0380E062E00E949A1D86E793E060E02B +:2025A00044E50E94A61D80E064E00E949A1D8EE494E060E00E94271E80915403882379F502 +:2025C00011E08EE995E30E943327812F1F9108958EE995E36EE173E041E00E94342A8823C5 +:2025E00009F464C081E08093540371CF873009F452C0873008F447C0883009F0A4CF8CE59A +:2026000094E060E00E94271E81E08093550380914A0399CF44E254E060E070E0A6CF8DE4BD +:2026200060E00E949A1D81E060E00E948B1D81E068E70E948B1D81E06EE70E948B1D81E0BB +:2026400069E70E948B1D81E069E70E948B1D81E06EE70E948B1D81E068E70E948B1D11E0FA +:202660008EE995E30E943327812F1F91089581E08093540370CF88EB94E060E00E94271E5A +:2026800080914A0360CF85E894E060E00E94271E80914A0358CF81E794E060E00E94271E1D +:2026A00080914A0350CF89E994E0ABCF8CED94E060E00E94271E1ACF1F931FB7F894E091BB +:2026C0004C03F0E0EE0FFF1FE850F041808180934C030E948A0910924C0310924D0310923A +:2026E000510310924E0310924F03109250031092530382E0809358031092590310925403EB +:20270000109255031092520310925D0310925C031092773510927635109295351092943553 +:2027200080E090E0FC01E858FA4C1082019688319105C1F711B8469A28988FE798E3A1E03B +:2027400081509040A040E1F700C0000080B18F7780935E0346988FE781B9289A80916400F0 +:20276000877F8093640083E48093800089E1809381000E94B0090E94DE1E0E94D21E1FBF7B +:202780001F910895FF920F931F93CF93DF938C01F0905203C0917635D09177358DDF0E94BA +:2027A000D21E80E060E00E949A1DFF2009F43FC08FE196E061E00E94271E80E061E00E94C4 +:2027C0009A1DC80160E044E50E94A61D8DB79EB708970FB6F8949EBF0FBE8DBFEDB7FEB753 +:2027E00031960FE513E0ADB7BEB712961C930E93119786E190E09383828387EC91E09583C4 +:202800008483D783C6830E94C2398DB79EB708960FB6F8949EBF0FBE8DBF80E065E00E942C +:202820009A1DC80160E044E50E94A61DFFCF89E096E061E00E94271E80E061E00E949A1D7B +:20284000C80160E044E50E94A61DF0CF1F93CF93DF930E94D21E80E060E00E949A1D84EF9E +:2028600095E060E00E94271E4A9BFECF8FEF99E6A8E181509040A040E1F700C000008EE9F4 +:2028800095E36AEC71E041E00E94342A882331F562E00E949A1D85EE95E060E00E94271E7D +:2028A00080E063E00E949A1D88ED95E060E00E94271E80E065E00E949A1D87EC95E060E0E5 +:2028C0000E94271E499B04C04A9B02C04C99FACF0E94D21EDF91CF911F9108958EE995E376 +:2028E00065E773E040E052E00E94C92497FD4DC01092BA351092B93586E195E10E94C93816 +:202900001FB7F8940E947338EC011FBF8EE995E30E94332780E062E00E949A1D209761F14E +:20292000ADB7BEB718970FB6F894BEBF0FBEADBFEDB7FEB731968FE593E012969C938E9309 +:20294000119786E190E09383828387EF91E095838483D783C6830E94C2398DB79EB7089660 +:202960000FB6F8949EBF0FBE8DBF8FE593E060E044E50E94A61D9DCF8FE593E067EE71E0E2 +:2029800046E150E00E94B339F0CF87ED91E0FADEAFCF80E060E00E949A1D0E94D21E80E06D +:2029A00060E00E949A1D8AE295E060E00E94271E80E062E00E949A1D87E195E060E00E94BC +:2029C000271E80E063E00E949A1D81E195E060E00E94271E499BFECF4A9BFCCF4C9BFACFA7 +:2029E00080E062E00E949A1D8DEF94E060E00E94271E80E063E00E949A1D80EF94E060E0A6 +:202A00000E94271E8FEF99E6A8E181509040A040E1F700C00000499B04C04A9B02C04C99FC +:202A2000FACF4A9B02C00C94D21E10CF2091B9353091BA3582E02030380759F0F901EB58F1 +:202A4000FC4F80812F5F3F4F3093BA352093B93508958EE995E365E773E040E052E00E949C +:202A6000C92497FD0BC01092BA351092B93585B198E0892785B920E030E0E0CF87ED91E0A9 +:202A800081DEF1CF909155039923E1F4E82FF0E0E45DFE4FE491F0E0262F30E02E173F0763 +:202AA000B4F4AF014F5F5F4F55954795E0FD14C031972E173F0759F06417B0F0862F8F5F91 +:202AC000841B0895262F30E02131310514F080E00895862F8F5F0895E42FF0E031972E179C +:202AE0003F0751F780E00895842F860F0895FF920F931F938C01F22E0E945520882379F1A8 +:202B0000C80165E773E30E94AD1F882391F1E9ECF3E3BF2DBB0FA0E0AB58BC4F81918D938E +:202B200085E3E537F807D1F7C80165E773E30E94AD1F882311F1E5E7F3E3BF2DBB0FA0E0EC +:202B4000AF5DBA4F81918D9383E3E93CF807D1F7C8010E943D201F910F91FF90089588E030 +:202B600092E010DEC80165E773E30E94AD1F882371F68CE192E006DECACF8CE192E002DEEF +:202B8000DACF2F923F924F925F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93FB +:202BA000DF93CF93CDB7DEB760970FB6F894DEBF0FBECDBF982E792E862E809155038823B5 +:202BC00009F4B7C004E210E062E1462E512C80E090E020E0FF2458E1E52E46E1A42EB12C62 +:202BE0003CE2C32E32E0D32E1801122F88589A4CDC018C9180FF35C080919035881661F15F +:202C0000809190352DB73EB72A5030400FB6F8943EBF0FBE2DBFEDB7FEB731962FE533E0CD +:202C2000ADB7BEB712963C932E931197B382A282D582C48286821782808711860E94C23909 +:202C40004DB75EB7465F5F4F0FB6F8945EBF0FBE4DBF8FE593E096DD5E2D583109F466C030 +:202C6000F12E1F5F812F90E0821593050CF45AC0BE2DB83109F43EC080915403882361F417 +:202C800066C0EE2DF0E0E858FA4C80818E7F808380818B7F8083E394FE1498F7EDB7FEB70D +:202CA00038970FB6F894FEBF0FBEEDBF31960FE513E0ADB7BEB712961C930E93119786E130 +:202CC00090E09383828381E492E095838483868217820E94C239EDB7FEB738960FB6F894BD +:202CE000FEBF0FBEEDBF80E065E024D7C80160E044E52CD760960FB6F894DEBF0FBECDBF8C +:202D0000CF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F905F904F903F902F +:202D20002F900895183109F4A3CF60CFF12EE12E98CFE62FF0E0E45DFE4FE4914E2E5524DE +:202D40008201000F111F01151105A1F240CFABD6D6D66B877C878D879E87FE1408F461C158 +:202D6000482D50E05A8749871A01220C331CC101880F991F880F991F880F991F820D931D77 +:202D80009C0140E050E029833A834B835C830E2DF101E457FF4F859194919C0140E050E052 +:202DA0002D833E834F8358871E2DAF2C42C0809091352091580330E040E050E069817A81A2 +:202DC0008B819C810E940A396B017C018091BB359091BC35A091BD35B091BE35C80ED91EC5 +:202DE000EA1EFB1E282D30E0429EC001439E900D529E900D1124AA2797FDA095BA2FC80E13 +:202E0000D91EEA1EFB1EC00ED11CE11CF11C2F853889322F2227330F2B583C4F892D972DEC +:202E2000B701A6010E947520882371F10F5FA01688F1402F50E0588B4F87FA01E858FA4C79 +:202E4000808180FDF3CF80915503882309F0AFCFC090BB35D090BC35E090BD35F090BE3541 +:202E6000C00ED11CE11CF11C2091580330E040E050E06D817E818F8198850E940A39C60E4E +:202E8000D71EE81EF91EC3CF86E592E07BDC0F5FA01678F6E12EFA2C80915503882309F086 +:202EA0004FC0F101E457FF4F65917491A090BB35B090BC35C090BD35D090BE35AE0CB11C20 +:202EC000C11CD11C80E090E02091580330E040E050E00E940A39A60EB71EC81ED91E0F2D65 +:202EE00010E00F5F1F4F0E191109222717FD2095322F892D972DB601A5010E9410228823FC +:202F000059F487C0F801E858FA4C80818E7F808380818B7F8083E394FE14D0F10E2D10E00A +:202F2000B801762F6627770F6B587C4F892D972D0E949E21882331F789E792E023DCE2CF52 +:202F40008091913590E0489E5001499EB00C589EB00C1124CC24B7FCC094DC2C8091BB3569 +:202F60009091BC35A091BD35B091BE35A80EB91ECA1EDB1EAE0CB11CC11CD11CB101660F02 +:202F8000771F660F771F660F771F620D731D9ACF892D972D0E945122882309F43EC089E17E +:202FA00080935D0384D5ABD5ADB7BEB71C970FB6F894BEBF0FBEADBFEDB7FEB731960FE51E +:202FC00013E012961C930E93119726E130E0338322832AE932E03583248329853A85378341 +:202FE00026832B853C854D855E85621B730B840B950B60877187828793870E94C2394DB735 +:203000005EB7445F5F4F0FB6F8945EBF0FBE4DBF6ACE86E692E0B6DB7FCF88E892E0B2DB9F +:20302000BECF282D30E03A8729871901220C331C33CF2F923F924F925F926F927F928F92FD +:203040009F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7CD54D0400FB692 +:20306000F894DEBF0FBECDBF18D526DBC1D89AD678948FE79AE1A6E081509040A040E1F7FB +:2030800000C0000010D58FE79AE1A6E081509040A040E1F700C00000499B05C04A9903C0AC +:2030A0004C9901C015D989E189831C821C8E1BA21EA28E010F5F1F4FC80160E00E94B62A4B +:2030C000882309F49FC42FE5822E23E0922EEFD4499905C04A9903C04C9B01C05ADCC801A7 +:2030E0000E949B05C8010E94AE072224332480915203882309F078C0F894D0904C03C09004 +:203100004E0310925103789480915303882309F07EC080915103882351F74B9B04C0079971 +:203120006DC0F1010995499918C080911C0390911D03009771F3019790931D0380931C039F +:20314000C8010E94AE078FEF94E3ACE081509040A040E1F700C00000DCCF4A9B49C04C9937 +:20316000D8CF80914A03813009F4A3C2823009F438C2809168008860809368008091680039 +:20318000846080936800809168008460809368008091680081608093680010924C030ED64E +:2031A00001D671D9882309F4A2CF8091540391E0892790915503992309F4826082B9459A1E +:2031C000A7E8B3E11197F1F700C000004598B2E4BA95F1F700C04298E1E0E093530380919D +:2031E0005203882309F488CF8FE593E0CBDA84CF80911C0390911D0301969ECF89B180FF6E +:2032000090CF86B180FF8DCF31998DCF8ACFED2CFF242DB73EB7285030400FB6F8943EBF73 +:203220000FBE2DBFEDB7FEB73196ADB7BEB712969C928E92119786E1482E512C538242824B +:20324000B6EC6B2EB2E07B2E75826482F782E6820E94C2392DB73EB7285F3F4F0FB6F8945E +:203260003EBF0FBE2DBF88E164E064D4C40160E044E56CD4AC2CBB248DB79EB708970FB691 +:20328000F8949EBF0FBE8DBFEDB7FEB73196ADB7BEB712969C928E92119753824282ABEC65 +:2032A0004A2EA2E05A2E55824482B782A6820E94C2392DB73EB7285F3F4F0FB6F8943EBFB5 +:2032C0000FBE2DBF88E364E035D4C40160E044E53DD480914D038D1509F45CC160914D03E0 +:2032E000C8014FDCD0924D03C0924F0380E090E0FC01E858FA4C20812D7F208301968831F1 +:203300009105B1F780915103882309F0F0CE80915003882309F030C13D2D303598F7809140 +:203320005503882309F05BC1F701E45DFE4F249180915903821710F01092590386B14B991B +:2033400008C3881F8827881F8EAF2C9D902D112423969FAF2397A701440F551FCA01880F1B +:20336000991F880F991F880F991F840F951F28968FAF289729969FAF299730E02A9DC00190 +:203380002B9D900D3A9D900D11242C01662457FC6094762C27964CAE5DAE6EAE7FAE2797B6 +:2033A0000E2CEF2C000CEE1CFF08000CEE1CFF1CAA0CBB1CA294B29460EFB622BA24A62294 +:2033C000BA245E2C5A285FAE852D90E084589E4F44575F4FFA01659074902B967FAE6EAEC4 +:2033E0002B972D2D2F7321962FAF2197E22FF0E0E458FE4F34912C963FAF2C97FC01F4919E +:203400002D96FFAF2D972296DFAE22972E96CFAE2E972401F6B0F094FF1CFF24FF1C09F4CE +:2034200013C16EAC6F1461F080E464E083D3FF2009F42FC182E494E060E009D421E02EAFEB +:2034400080915D03813009F42AC180915503882309F4ABC0E0905903F8946E2C772458E71A +:20346000852E55E3952E860C971CD4018C9181FD8FC08C9182FD8CC08C9184608C9381E031 +:203480007894882309F441C080915503882309F0F7C02B966EAD7FAD2B9780915903A0904C +:2034A000BB35B090BC35C090BD35D090BE35A80EB11CC11CD11C27968CAD9DADAEADBFAD02 +:2034C0002797A80EB91ECA1EDB1E80E090E02091580330E040E050E00E940A39A60EB71E16 +:2034E000C81ED91EE0D280917535882309F4B7C0C801B601A5012E2DFADAD9D2D4018C9171 +:2035000082608C938C918B7F8C9380915903882301F5FF2059F085B1B8E08B2785B980911F +:203520005D03823018F0815080935D0320915C03275E20935C032D3708F08CC030E08091BD +:203540005A0390915B03821B930B909389008093880080915503882379F122E3F22E06C0A4 +:203560008EE40E94850FFA9409F4BCC0809151038823B1F34201BBCD80E464E0DBD288E45C +:2035800094E060E064D3809151038823E1F3BACE80E076CF80915503882309F4B3CE80918C +:2035A0004F038C1509F09ACEADCEE090590323963FAD2397E30E50CFB7E3EB2EF12C0AC067 +:2035C0008FEF0E94510F0894E108F108E114F10409F4EFC080915103882391F3CBCF22E126 +:2035E000A7CE80914B03815080934B03C80161E00E943C2A80914B03882389F0FF249F2D41 +:20360000ADE09A9FB00111246B587E4CC80141E00E945A2AF39480914B03F81680F3109258 +:203620001D0310921C03BED3C8010E949B05C8010E94AE078FEF99E6A8E181509040A040E6 +:20364000E1F700C0000053CDC80122966FAD229798DAE7CE10925C0320E030E070CF930151 +:20366000322F2227330F2B583C4FC801B601A5013CD5882309F041CF87ED91E083D83DCF19 +:2036800028969FAD289729968FAD2997692F782F04CF8CE394E060E0DAD22B9A1EAE109292 +:2036A0005D0380E065E046D286E294E060E0CFD2CCCEF0904B03AF2DBDE0AB9FC00111240F +:2036C0008B589E4C6EE173E04DE050E00E94B339F394F0924B03C8016EE173E041E00E940B +:2036E0005A2A9DCF9CE0F92E80915103882309F041CF0E94850FFA94B9F7EFEFFFEFF0935B +:203700005703E09356030E94600F0E94600F0E94600F80915103882309F02CCF8EEF0E942D +:20372000850F80915103882309F024CF22968FAD22970E94850F80915103882309F01ACF24 +:203740002E968FAD2E970E94850F80915103882309F010CF809159038F5F0E94850F8091E4 +:203760005103882309F006CF82E00E94850FF09056038091570390915103992309F0FACEAE +:203780000E94850F80915103882309F0F3CE8F2D0E94850FFF2408C08EE40E94850FF3941D +:2037A000FF2DF63109F4F1C0809151038823A1F3E1CE80915803823009F4E4C0F2E0FF2EF7 +:2037C000E090590380915103882309F0D3CE85ED0E94510F80915103882309F0CBCE8AEAE9 +:2037E0000E94510F80915103882309F0C3CE86E90E94510F80915103882309F0BBCE2C9668 +:203800008FAD2C970E94510F80915103882309F0B1CEE0915903F0E0E458FE4F84910E9442 +:20382000510F80915103882309F0A4CE2D968FAD2D970E94510F80915103882309F09ACE77 +:20384000EF2DF0E0E458FE4F84910E94510F80915103882309F08ECE2196EFAD2197EE2559 +:203860002FADE227EF25EF73F0E0E458FE4F84910E94510F80915103882309F07BCE8EEDB0 +:203880000E94510F80915103882309F073CE8AEA0E94510FEAE0FE2E80915103882309F067 +:2038A00069CE8FEF0E94510FFA94B1F780915103882309F05FCE85ED0E94510F809151030C +:2038C000882309F057CE8AEA0E94510F80915103882309F04FCE8DEA0E94510F80915103A5 +:2038E000882309F047CEE0915903F0E0E458FE4F84910E94510FC301982F8827990F8B580D +:203900009C4F0E94AC0F80915103882309F032CE8EED0E94510F80915103882309F02ACED8 +:203920008AEA0E94510F80915103882309F022CE8FEF0E94510F22968FAD2297609159039E +:20394000A1D8809359034B9B65CD2296DFAC229742014598429A10925303C8016D2D11D92A +:203960008FE79AE1A6E081509040A040E1F700C000000E945C13C8010E949B05C8010E9430 +:20398000AE07B5CBA2E2FA2E1BCFFF2480915103882309F0EFCD0E94850FF3942F2D2C30FF +:2039A000A9F78FEF9FEF90935703809356030E94600F0E94600F0E94600F8091510388232F +:2039C00009F0D8CD8BEF0E94850F6301DC2CCC24DD0CA5E7B3E0CA0EDB1EEE24FF240AC065 +:2039E0000E94850F0894E11CF11CF0E0EF16F2E0FF06B9F1F60181916F01909151039923EB +:203A000079F3B8CDADB7BEB71A970FB6F894BEBF0FBEADBFEDB7FEB731969FE5892E93E056 +:203A2000992E12969C928E92119786E190E09383828382EB92E09583848389818683178285 +:203A40008B81808711860E94C239EDB7FEB73A960FB6F894FEBF0FBEEDBFC4010E94C21333 +:203A600036CBF09056038091570390915103992309F080CD0E94850F80915103882309F04B +:203A800079CD8F2D0E94850F56CF81E090E00C94770980E090E00C94770914BC83E085BD73 +:203AA00081E085BB089581E080936E00089510926E0008951F920F920FB60F9211248F938D +:203AC0009F93AF93BF938091C3359091C435A091C535B091C6350196A11DB11D8093C33568 +:203AE0009093C435A093C535B093C635BF91AF919F918F910F900FBE0F901F9018952FB712 +:203B0000F8946091C3357091C4358091C5359091C6352FBF089590E59CBD1DBC882341F001 +:203B20005E9A2A986EBD0DB407FEFDCF2A9A08955E98F7CF1F93162F682F606880E0EBDF71 +:203B4000612F606480E0E7DF1F910895AF92BF92CF92DF92EF92FF920F931F93CF93DF9300 +:203B6000D62EC42EE82EF92EBB248FE7A82EF70101917F01002359F4DF91CF911F910F914D +:203B8000FF90EF90DF90CF90BF90AF900895BC1498F70D3609F183E0089F80011124E801D9 +:203BA000CB52DA4F09521A4FFE016491660FD1106A2581E0B0DFB394C017D10749F4BC142F +:203BC000B0F6DD20C1F16FE781E0A5DFB394CFCF2196BC1460F6E8CFDD2079F163E481E0CD +:203BE0009ADFB394BC1408F0C2CFDD2051F16BE781E091DFB394BC1408F0B9CFDD2029F19C +:203C000067E681E088DFB394BC1408F0B0CFDD20D1F06BE781E07FDFB394BC1408F0A7CFAD +:203C2000DD2069F067E481E076DFB394BC1408F09ECFDD2041F660E0C7CF6CE3D0CF68E36E +:203C4000F2CF64E0D5CF64E0E5CF68E1DACFCF92DF92EF92FF920F931F93CF93DF93D62EC1 +:203C60008C010F5F1F4F2FE7C22EF8013197E491EE2331F1ED3679F183E0E89FF0011124CF +:203C8000EF01CB52DA4F98EDE92E95E0F92EEE0EFF1EFE016491660FD1106C2581E03BDF47 +:203CA0002196CE15DF05A9F7DD2099F06FE781E032DF0F5F1F4FF8013197E491EE23D1F6AE +:203CC000DF91CF911F910F91FF90EF90DF90CF90089560E0ECCFDD2089F081E063E41BDF38 +:203CE00081E06BE718DF81E067E615DF81E06BE712DF81E067E40FDF6FE7D9CF81E06CE38C +:203D00000ADF81E064E007DF81E068E104DF81E064E001DF81E068E3FEDE60E0C8CFEF923D +:203D2000FF920F931F93CF93DF93E82EF92EF70101917F010023E1F00D3609F183E0089F48 +:203D400080011124E801CB52DA4F08521A4FFE016491606481E0DFDE2196C017D107B9F7CF +:203D600081E060E4D8DEF70101917F01002321F7DF91CF911F910F91FF90EF90089581E077 +:203D80006EE5C9DE81E062E4C6DE81E06CE4C3DE81E062E4C0DE81E06CE5BDDE81E060E455 +:203DA000BADEC5CFCF93DF93C8EFD1E081E060E0B2DE2197D9F7DF91CF9108958FEB8093E8 +:203DC000C73584E18093C83584E08093C935569A279A259A229A209A2A98289A8FE798E3A2 +:203DE000A1E081509040A040E1F700C0000028988FE798E3A1E081509040A040E1F700C0DE +:203E00000000289A8FE798E3A1E081509040A040E1F700C0000080E090E00E94023C813FE5 +:203E2000E1F080E090E061EF0E940A3C6091C73581E090E00E940A3C80E061E26CDE609125 +:203E4000C73580E068DE6091C83580E064DE80E060E261DE80E06CE05ECE81E090E00E9404 +:203E6000023C8093C735E8CFFC014181842F90E09C013595279520652CBD40FD06C081E067 +:203E8000463019F08DBD2C98089580E08DBD2C980895BF92CF92DF92EF92FF920F931F9364 +:203EA000CF93DF938C016B017A0129DEEB01BB24BA94BEBC0DB407FEFDCF8EB5F80182834D +:203EC0008F3FB1F41CDE6C1B7D0B81E06D32780780F381E1F80180832C9A80E0DF91CF9120 +:203EE0001F910F91FF90EF90DF90CF90BF9008958E3F19F08FE08083EFCFE114F104F1F0D9 +:203F00000894E108F1088FEF8EBDE114F10471F0F60180E090E03FEF0DB407FEFDCF2EB5A5 +:203F200021933EBD01968E159F05B0F30DB407FEFDCF8EB5F601EE0DFF1D80838FEF8EBDA2 +:203F40000DB407FEFDCF8EB58FEF8EBD0DB407FEFDCF8EB52C9A81E0C1CF0F931F93CF9381 +:203F6000DF93EC018B0180DFCE01B80140E052E090DFDF91CF911F910F910895FF920F93BE +:203F80001F93CF93DF93EB01BADD8B01FF24FA94FEBC0DB407FEFDCF8EB58F3F69F0AFDD99 +:203FA000601B710B6C177D0798F380E0DF91CF911F910F91FF90089581E0DF91CF911F91EB +:203FC0000F91FF900895DF92EF92FF920F931F93CF93DF93EC01D62E79018A0145DFCE0181 +:203FE0006CE271E0CBDF8D2D80648EBD0DB407FEFDCF28E130E0D801C701022E04C0B69504 +:20400000A795979587950A94D2F78EBD0DB407FEFDCF285030408FEF283F380761F7DD2077 +:20402000E9F08D2D883001F587E88EBD0DB407FEFDCF8D2D8C30D1F02FEF9FEF9EBD0DB4F4 +:2040400007FEFDCF8EB58A8387FD0AC0DF91CF911F910F91FF90EF90DF90089585E9E5CF95 +:204060002223A1F32150EACF8FEFDFCF8FEF8EBD0DB407FEFDCF8EB5DFCFCF93DF93EC0104 +:20408000F3DECE016CE020E030E0A9019CDF882339F083E088832C9A80E0DF91CF9108952A +:2040A0002C9A81E0DF91CF910895CF93DF93EC019A01AB018B81833039F069E0220F331FB0 +:2040C000441F551F6A95D1F7CE0162E17CDF882339F085E088832C9A80E0DF91CF910895FE +:2040E0002C9A81E0DF91CF910895CF92DF92EF92FF920F931F93CF93DF93EC017A018B012C +:2041000069018B81833039F0A9E0EE0CFF1C001F111FAA95D1F7CE0161E1A801970153DFD5 +:20412000882369F084E088832C9A80E0DF91CF911F910F91FF90EF90DF90CF900895CE017E +:20414000B60140E052E0A5DEF1CF8F929F92BF92CF92DF92EF92FF920F931F93DF93CF9364 +:204160000F92CDB7DEB74C01B62EFC0113821082C6DC8B01249A2C9A2698259A279A249A82 +:204180002C9A85E0F401818382E58CBD1DBC8AE09FEF9EBD0DB407FEFDCF8150D1F7C4012F +:2041A00060E020E030E0A9010EDF782FF40182838130C9F0A4DC601B710BF7E0613D7F079B +:2041C00070F381E0F40180832C9A80E00F90CF91DF911F910F91FF90EF90DF90CF90BF9013 +:2041E0009F908F900895C40168E02AEA31E040E050E07983E8DE798182FF1FC0F40173834B +:20420000CC24DD247601C40167E320E030E0A901DADEC40169E2A7019601D5DEF4018283B9 +:204220008823D9F06CDC601B710BF7E0613D7F0750F38AE0F4018083C7CF84E02FEF2EBD28 +:204240000DB407FEFDCF9EB5F40192838150B9F79A3A79F082E08083B7CF83818230B1F06F +:204260002C9AFB2DF73070F088E1F401808380E0ADCF82E0F4018383C12CD12CE12CB0E4A4 +:20428000FB2EC1CFF401B18281E0A0CFC4016AE320E030E0A90197DE882321F088E0F40113 +:2042A000808392CF8FEF8EBD0DB407FEFDCF8EB5807C803C19F483E0F401838383E09FEFE8 +:2042C0009EBD0DB407FEFDCF2EB58150C9F7C8CFFC016EBDA42FB52F80E090E00DB407FE71 +:2042E000FDCF2C912EBD0DB407FEFDCF11962C9111972EBD0296129622E08030920771F7CE +:204300000DB407FEFDCF8FEF8EBD0DB407FEFDCF8FEF8EBD0DB407FEFDCF8FEF8EBD0DB4CB +:2043200007FEFDCF8EB582838F71853029F083E180832C9A80E0089581E008950F931F931A +:20434000CF93DF93EC018B018FDDCE0168E572E015DE882349F485E188832C9A80E0DF9154 +:20436000CF911F910F910895CE016CEFA801B0DF882389F32C9A81E0DF91CF911F910F9120 +:204380000895CF92DF92EF92FF920F931F93CF93DF93EC017A018B0169018B81833039F02E +:2043A00089E0EE0CFF1C001F111F8A95D1F7CE0168E1A801970107DE882369F086E0888396 +:2043C0002C9A80E0DF91CF911F910F91FF90EF90DF90CF900895CE016EEFA60179DF882348 +:2043E00079F3CE0168E572E0C9DD882319F487E18883E6CFCE016DE020E030E0A901E3DDC7 +:20440000882319F086E18883DBCF8FEF8EBD0DB407FEFDCF8EB58823A9F72C9A81E0D2CF1B +:20442000AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC015A016B017801890167E3DD +:2044400020E030E0A901BFDDCE0167E1A8019701BADD882379F089E088832C9A80E0DF91F9 +:20446000CF911F910F91FF90EF90DF90CF90BF90AF9008958B81833039F099E0AA0CBB1C97 +:20448000CC1CDD1C9A95D1F7CE0169E1A60195019ADD882319F087E08883DFCF2C9A81E07C +:2044A000DECFCF93DF93EC01DFDCCE0168E572E065DD882359F08DEF8EBD0DB407FEFDCFD6 +:2044C000CE0168E572E05ADD882339F482E188832C9A80E0DF91CF9108952C9A81E0DF91C7 +:2044E000CF910895CF93DF93EC019C012C5F3F4F898D9A8D41E050E060E070E00E94042D57 +:204500008823D9F08D899E89AF89B88D0097A105B10579F48C819D81AE81BF818D8B9E8B32 +:20452000AF8BB88F89818068898381E0DF91CF91089581E0DF91CF91089580E0DF91CF9130 +:204540000895CF92DF92EF92FF921F93CF93DF93EC0189899A89AB89BC89803E2FEF920744 +:204560002FE1A20720E0B20748F080E0DF91CF911F91FF90EF90DF90CF900895CE01B2DFD8 +:20458000882399F30E94D82A882379F3E98DFA8DCC80DD80EE80FF808EEF9FEFAFEFBFEF3F +:2045A000C80ED91EEA1EFB1E058404C0CC0CDD1CEE1CFF1C0A94D2F786859785A089B189D9 +:2045C000C80ED91EEA1EFB1E81E08093D637C092D035D092D135E092D235F092D33580E04A +:2045E00092E0E4EDF5E3DF019C011D9221503040E1F7E98DFA8D84818230C0F011E006C0A0 +:204600001F5FE98DFA8D8481181780F4B701A601410F511D611D711D8091D4379091D53705 +:2046200024ED35E3AEDE882359F79FCF20E032E040E050E0058404C0220F331F441F551F53 +:204640000A94D2F789899A89AB89BC89820F931FA41FB51F898B9A8BAB8BBC8B81E086CFFF +:20466000CF93DF93EC018C859D85AE85BF8541E0662309F440E0BC01CD01DAD7882381F0B0 +:20468000288930E0220F331F22953295307F3227207F32272C523A4CC901DF91CF9108951D +:2046A00020E030E0C901DF91CF9108956F927F928F929F92AF92BF92CF92DF92EF92FF92D9 +:2046C0000F931F93DF93CF9300D000D0CDB7DEB76C014B013A01DC015596ED90FD900D9195 +:2046E0001C915897E114F10401051105F1F05E010894A11CB11C10C0D801C7010196A11DEC +:20470000B11D29813A814B815C8182179307A407B507F9F47C018D01F601818D928DB8014E +:20472000A7019501CAD7882339F780E00F900F900F900F90CF91DF911F910F91FF90EF90B5 +:20474000DF90CF90BF90AF909F908F907F906F900895D60159966D917C915A97FB01878936 +:20476000803109F44CC0283F8FEF38078FEF48078FE05807D0F2F60185899689A789B08D6D +:204780000297A109B109FB01058404C0880F991FAA1FBB1F0A94D2F7268537854089518970 +:2047A000820F931FA41FB51FF40180839183A283B383FB0186859785A089B1890197A109F0 +:2047C000B1092481820F911DA11DB11DA80197012250304040405040058404C0220F331FAC +:2047E000441F551F0A94D2F7820F931FA41FB51FF30180839183A283B38381E097CF283F0D +:20480000FFEF3F07F0E04F07F0E05F0708F0B3CF8CCFE82FF92F80E090E03EE209C0DB015F +:20482000A90FB11D2C939F5F8F5F31968B3061F020812032C9F3883091F7DB01A90FB11D23 +:204840003C939F5F2081EBCF690F711DFB01108208951F93FB012BE030E231932150E9F71F +:20486000A82FB92F30E017E09A2F8B2F2D91222351F4FA019083818381E0FB019081903265 +:2048800079F01F9108952F32A1F32E3261F082E597E0FC010196E491EE2351F02E17C9F77E +:2048A00080E01F9108951A30D9F338E01AE0DCCF1317B0F32132A0F32F3790F7FB01E30FEA +:2048C000F11D822F81568A3108F4205220833F5FCBCF0F931F93CF93DF93EC018B018B8191 +:2048E000882331F4FB018789803141F08032F1F180E0DF91CF911F910F91089582E08B83D9 +:204900001D8A1E8A1F8A188E808D918DA0E0B0E0880F991FAA1FBB1F880F991FAA1FBB1FDA +:20492000880F991FAA1FBB1F880F991FAA1FBB1F880F991FAA1FBB1F898B9A8BAB8BBC8BEB +:204940001A8F098F81E089831C821D821E821F82188619861A861B861C861D861E861F861F +:20496000188ADF91CF911F910F91089583E08B83F801428D538D648D758D4D8B5E8B6F8B11 +:20498000788F9E012F5E3F4FC80124D78823C1F6AFCF2F923F924F925F926F927F928F921B +:2049A0009F92AF92BF92CF92DF92EF92FF920F931F93CF93DF938C01362FE72F2A01DC0118 +:2049C00013962C911397222329F011968C91119780FD16C02FEF3FEFC901DF91CF911F9114 +:2049E0000F91FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F902F90089558 +:204A0000E801C988DA88EB88FC88488559856A857B854201AA24BB24D701C601841B950B9B +:204A2000A60BB70B88169906AA06BB0608F093C04114510409F4BEC0832E9E2E6201A4E081 +:204A40002A2E312C200E311E612CF2E07F2E60C0FF2009F07AC0411551056105710509F025 +:204A6000ABC0E8018D899E89AF89B88D8C839D83AE83BF8346855785608971894F0D511D32 +:204A8000611D711D0297A109B109058404C0880F991FAA1FBB1F0A94D2F7480F591F6A1F0F +:204AA0007B1FE301CA19DB09CC16DD0608F4E601E2E0C030DE0709F452C0CB01BA0140E0BC +:204AC000B7D5882309F486CF95012C523A4CC401B901AE010E949C39AE0160E070E0F801D6 +:204AE00080859185A285B385480F591F6A1F7B1FD80118964D935D936D937C931B97CC1A4C +:204B0000DD0A09F457C08C0E9D1E13962C911397EFEFAE2EE1E0BE2EA422B5222230B9F135 +:204B2000D8015996ED91FC915A97DB01CA0129E0B695A795979587952A95D1F7F480FA94A9 +:204B4000F822A114B10409F483CFE8018C819D81AE81BF818FCF2601441A550A69CF809174 +:204B6000D0359091D135A091D235B091D335481759076A077B0709F4A0CF8091D43790912D +:204B8000D5379401B2DA882309F0A6CF23CF39E076956795579547953A95D1F7E801E98DFF +:204BA000FA8D828D938DA48DB58D480F591F6A1F7B1F77CF920110CFD80114964D915D91D3 +:204BC0006D917C911797CF01910177D5882309F401CFE801E98DFA8D8C819D81AE81BF8176 +:204BE00049CFDF93CF930F92CDB7DEB7BE016F5F7F4F41E050E0CDDE8130910539F02FEF2A +:204C00003FEFC9010F90CF91DF910895298130E0C9010F90CF91DF910895EF92FF920F934C +:204C20001F93CF93DF93EC018B81823050F420E030E0C901DF91CF911F910F91FF90EF90F7 +:204C40000895E884F9840A851B85CE01CADF97FDEECF88859985AA85BB854F96A11DB11DCB +:204C600088879987AA87BB87D801C70115E0B695A795979587951A95D1F78F70282F30E050 +:204C8000220F331F22953295307F3227207F32272C523A4CCECF8F929F92AF92BF92CF922D +:204CA000DF92EF92FF920F931F93CF93DF93EC014A015B012B81222309F465C089899A896D +:204CC000AB89BC8984179507A607B70708F45BC0223009F452C081149104A104B10409F4C0 +:204CE0006AC0488559856A857B85E98DFA8D258530E0275F3F4FDB01CA010197A109B10982 +:204D0000022E04C0B695A795979587950A94D2F7850174010894E108F1080109110904C008 +:204D200016950795F794E7942A95D2F7E816F9060A071B07B0F58D899E89AF89B88D8C8300 +:204D40009D83AE83BF8384E0C82ED12CCC0EDD1E0FC04C815D816E817F81898D9A8D960157 +:204D6000ACD40894E108F10801091109882359F0E114F1040105110561F788869986AA8662 +:204D8000BB8681E001C080E0DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F9078 +:204DA0000895411551056105710529F2E81AF90A0A0B1B0BC8CF1C821D821E821F821886C0 +:204DC00019861A861B8681E0DFCF0F931F93CF93DF93EC018B81882349F0898187FD0EC083 +:204DE000E7D3DF91CF911F910F91089581E0888380E0DF91CF911F910F910895CE0161E0A3 +:204E00002FDC8C01009791F3FC018081853E71F38B818230F8F08D899E89AF89B88DF80161 +:204E2000938F828FB58BA48BE091CC35F091CD35309759F0B8016A5E7F4FC8014896099537 +:204E4000F801808D918D938B828B89818F778983AFD3C7CF89899A89AB89BC89848F958FEA +:204E6000A68FB78FD8CFCF93DF93EC01AEDF1B82DF91CF9108956F927F928F929F92AF9213 +:204E8000BF92CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB7DEB77C015A016B01B8 +:204EA000DC0113968C9113978130A1F080E00F900F900F900F90CF91DF911F910F91FF90D8 +:204EC000EF90DF90CF90BF90AF909F908F907F906F90089511968C91119781FFE7CFF70164 +:204EE00081899289A389B48984179507A607B707E8F20097A105B10529F1F70160847184CA +:204F000082849384C701B601A501C5DE882371F2A114B104C104D104B9F4D70155964D914C +:204F20005D916D917C91589759968D919C915A97A3D6882309F4BACFF701158A168A178ADC +:204F4000108E40C081E0B3CFD70114964D915D916D917C91179759968D919C915A979E01FF +:204F60002F5F3F4FAAD3882309F4A0CFD7015996ED91FC915A9749815A816B817C81878920 +:204F80008031C9F1483F8FEF58078FEF68078FE07807C0F4CF0170D6882309F487CFD701C7 +:204FA00014964D915D916D917C91179759968D919C915A970FEF1FEF2FEF3FE086D4882349 +:204FC00009F474CFF701A18AB28AC38AD48A818180688183C701F9DE882309F467CFB60165 +:204FE000A5016A147B048C049D0410F4B401A301C70151DE5CCF483FBFEF5B07B0E06B07C5 +:20500000B0E07B07F8F6C6CF1F93CF93DF93EC01142FE62FF0E0EE0FFF1FE295F295F07FD8 +:20502000FE27E07FFE27DF01AC52BA4C1B968C911B97817149F0842F827131F01B8280E074 +:20504000DF91CF911F9108958091D0359091D135A091D235B091D3358C879D87AE87BF87C3 +:20506000688BEC52FA4C84899589A0E0B0E0DC01992788278D8B9E8BAF8BB88F428D538DC1 +:2050800060E070E0482B592B6A2B7B2B4D8B5E8B6F8B788F838590E0887190700097F1F49F +:2050A000848D958DA68DB78D898B9A8BAB8BBC8B81E08B83812F8F7089831C821D821E8289 +:2050C0001F82188619861A861B8614FD17C015FD1EC081E0DF91CF911F9108958031910514 +:2050E00009F0ACCF9E012F5E3F4F898D9A8D72D3882309F4A3CF84E08B83DCCFCE0140E0DA +:2051000050E0BA01B8DE882311F780E099CF49895A896B897C89CE01BEDD92CF8F929F92C8 +:20512000AF92BF92CF92DF92EF92FF920F931F93CF93DF935C01EB01C42E952E822E898D0D +:205140009A8DD5015A969C938E935997CB0140E050E0BA01A0DDDD24E884F9840A851B85B5 +:2051600089899A89AB89BC89E816F9060A071B0708F040C0CE0151DDFC01009709F476C095 +:20518000D801C70115E0B695A795979587951A95D1F7182F1F708081882391F0853E81F0FC +:2051A0008C2D992DBF014BE050E00E948F39009799F687FC5BC0C501612F482D25DF57C041 +:2051C000DD20A9F42091D0353091D1354091D2355091D335D5011C962D933D934D935C9310 +:2051E0001F9750961C9350978081DD24D394882309F0B2CF86FE3AC081FE38C0DD2009F004 +:2052000043C08B81823091F1CE019BD9882371F1C4EDD5E310E07E01EC2FFF2D80E2DF019A +:205220001D928A95E9F7DE018C2D992DFC018BE001900D928150E1F7E091CC35F091CD352C +:20524000309761F1BE01625F7F4FCE0140960995888999892E853F859B8B8A8B998F888F80 +:205260003F8B2E8BA5D1882309F0A5CF80E0DF91CF911F910F91FF90EF90DF90CF90BF9072 +:20528000AF909F908F900895F5011089C50161E0E7D9EC01009709F0BECFE8CF81E298E2F0 +:2052A000998B888B80E098E09F878E8720E038E081E298E2D1CF2F923F924F925F926F92AA +:2052C0007F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB7C4549C +:2052E000D0400FB6F894DEBF0FBECDBF2C013B018E010E5B1F4FD80111965C934E9325967D +:205300002FAF25971C861F861FA21AA66115710509F45FC0FC018381882309F05AC0CA0199 +:20532000DA012C912F3209F470C073013CE0832E912C8C0E9D1E64015E010894A11CB11C0A +:2053400027E2222E312C2C0E3D1EB501A80181DA882369F1D801ED91FC91119780818F32F5 +:2053600041F43196D8011196FC93EE9381918F32C9F3882309F46FC0C601B701A50121E015 +:20538000CDDE8823A1F0E614F70421F0C7011DDDF7011382C814D904C9F076016401D801AA +:2053A0008D919C91B501A80154DA882399F600E08AA5882321F0CE01879607DD1AA68F856C +:2053C000882341F0CE010C9600DD04C061017401E6CF00E0802FCC5BDF4F0FB6F894DEBF81 +:2053E0000FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F906E +:205400005F904F903F902F9008959A012F5F3F4FC901F80131832083D9014C912F5F3F4FEF +:205420004F32B1F3F30123812250223008F47DCF87E2E82EF12CEC0EFD1ED30159966D9131 +:205440007C915A97C70145DA882309F4B0CFF801808191816BCFC201B701A50125962FAD42 +:2054600025975CDE082FA4CFFB01242F6091CA357091CB35AF011FCF0F931F93CF93DF9386 +:20548000EC01662399F08C010E5D1F4F1093CB350093CA35C801E7DCBE016C5F7F4FC801C5 +:2054A00018DADF91CF911F910F9108958C010E5D1F4FF0CFDF92EF92FF920F931F93DF93CF +:2054C000CF93CDB7DEB76C970FB6F894DEBF0FBECDBFFB01D42E19821C8220812F3229F1B4 +:2054E00022E2E22EF12CE80EF91E8E010F5F1F4FC801B701AF0121E0DEDE8823F1F08C817C +:20550000823070F1D701F8018BE101900D928150E1F7DD2021F0F092CB35E092CA3521E060 +:20552000C8012C8FA0DC2C8D0CC021812223C1F6642FA2DF282F8C8102C08C8120E0882356 +:2055400089F4822F6C960FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF9008959A +:2055600020E0EDCF8E010F5F1F4FDACF0F931F93CF93DF938C010E94A520882331F480E00F +:20558000DF91CF911F910F910895E8012496CE01B80141E0CDD3882321F0C80161E06CDF51 +:2055A000EFCFCE01B80140E0C3D3882341F3F5CF8091D637882311F481E008954091D035AA +:2055C0005091D1356091D2357091D3358091D4379091D53724ED35E30E94C121882321F130 +:2055E0004091D7375091D8376091D9377091DA37411551056105710521F41092D63781E01C +:2056000008958091D4379091D53724ED35E30E94C121882359F01092D7371092D837109200 +:20562000D9371092DA37E9CF80E0089580E00895DF92EF92FF920F931F937B018C01D42E13 +:205640008091D0359091D135A091D235B091D3358E159F05A007B107F1F0AADF882339F4A4 +:2056600080E01F910F91FF90EF90DF9008958091D4379091D537B801A70124ED35E30E94EB +:205680007520882369F3E092D035F092D1350093D2351093D335DD2049F081E08093D63773 +:2056A0001F910F91FF90EF90DF90089581E01F910F91FF90EF90DF900895CF92DF92EF9262 +:2056C000FF920F931F93CF93DF93EC017A018B01690189859A85AB85BC850196A11DB11DF2 +:2056E00084179507A607B70730F0EF89E03169F0E03209F445C080E0DF91CF911F910F9172 +:20570000FF90EF90DF90CF9008959927872F762F652F2B893C894D895E89620F731F841F85 +:20572000951F2091D0353091D1354091D2355091D335621773078407950729F040E078DFCD +:205740008823C9F2EF89E03169F18FE790E0A0E0B0E0E822F9220A231B23F701EE0FFF1F67 +:20576000EE0FFF1FEC52FA4C80819181A281B381BF70F60180839183A283B38381E0BCCF9C +:20578000CB01BA0127E096958795779567952A95D1F72B893C894D895E89620F731F841FC9 +:2057A000951FBFCF8FEF90E0A0E0B0E0E822F9220A231B23F701EE0FFF1FEC52FA4C808181 +:2057C0009181A0E0B0E0F60180839183A283B38381E092CF4F925F926F927F928F929F9246 +:2057E000AF92BF92CF92DF92EF92FF920F931F93DF93CF9300D000D0CDB7DEB78C014983F9 +:205800005A836B837C832901842F952FA62FB72FAC01BD01CC24DD2476015E010894A11CD7 +:20582000B11C612CE2E07E2E812C912CC801950144DF882309F447C0D401C301F8010584EA +:2058400004C0880F991FAA1FBB1F0A94D2F7C80ED91EEA1EFB1E49815A816B817C8187899F +:20586000803119F1483F8FEF58078FEF68078FE07807E0F2F201C082D182E282F38281E09A +:205880000F900F900F900F90CF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F90B4 +:2058A0007F906F905F904F900895483FFFEF5F07F0E06F07F0E07F07E8F6C8019501FDDEE0 +:2058C000882309F0B9CF80E0DBCF4F925F926F927F928F929F92AF92BF92CF92DF92EF9277 +:2058E000FF920F931F93CF93DF93EC016A017B0128013901423051056105710590F0898586 +:205900009A85AB85BC850196A11DB11D84179507A607B70730F08F89803109F456C0803284 +:2059200091F080E0DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F90A0 +:205940005F904F9008954A015B0117E0B694A794979487941A95D1F78B899C89AD89BE8946 +:20596000880E991EAA1EBB1EC501B40141E060DE8823B9F28F898031A9F18FE790E0A0E040 +:20598000B0E0C822D922EA22FB22F601EE0FFF1FEE0FFF1FEC52FA4C40825182628273824A +:2059A0008A89823078F18D819E81AF81B885880D991DAA1DBB1D8093D7379093D837A093AF +:2059C000D937B093DA3781E0ADCF852E962EA72EBB248B899C89AD89BE89880E991EAA1E90 +:2059E000BB1EC2CF8FEF90E0A0E0B0E0C822D922EA22FB22F601EE0FFF1FEC52FA4C5182C8 +:205A00004082CECF81E08ECF2F923F924F925F926F927F928F929F92AF92BF92CF92DF923D +:205A2000EF92FF920F931F93DF93CF93CDB7DEB767970FB6F894DEBF0FBECDBF1C014987E1 +:205A40005A876B877C873E872D87FC0181859285A385B4859C01AD012F5F3F4F4F4F5F4FC9 +:205A60002D833E834F835887ED85FE854080518062807380411451046104710409F4BEC0AA +:205A80000894411C511C611C711C1F860097A105B10509F454C0D301C201CC24DD247601EE +:205AA0008E010F5F1F4F4C8A5D8A6E8A7F8A2EC04C015D01C101B501A4019801FEDD8823E8 +:205AC00009F43DC089819A81AB81BC810097A105B10509F44EC0A50194012F5F3F4F4F4F4B +:205AE0005F4F2C8B3D8B4E8B5F8BDA01C9010894C11CD11CE11CF11CF1012185328543858A +:205B00005485C216D306E406F506C8F44D805E806F807884481659066A067B0648F682E076 +:205B2000882E912CA12CB12C8C8A9D8AAE8ABF8AC101B501A4019801C0DD882319F680E01D +:205B400067960FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF9077 +:205B60009F908F907F906F905F904F903F902F900895D501C4010196A11DB11D2C013D01A7 +:205B80002C893D894E895F89421A530A640A750A29853A854B855C85421653066406750671 +:205BA00009F0A5CF4C885D886E887F88C101B501A4010FEF1FEF2FEF3FE087DE882309F44F +:205BC000BECF481459046A047B0458F59501840107C0970186014C145D046E047F0408F591 +:205BE000680179010894C108D108E108F108C101B701A6016ADE882361F7A1CFF101408014 +:205C0000518062807380F1E0FF8729853A854B855C85213031054105510509F437CF1F869E +:205C200035CFAD85BE854D915D916D917C9113974115510561057105C1F4ED85FE85408276 +:205C4000518262827382FF85FF2369F00894411C511C611C711CD1014D925D926D927C927C +:205C6000139781E06DCF81E06BCFC101930182012CDE882311F763CFAF92BF92CF92DF9216 +:205C8000EF92FF920F931F93DF93CF9300D000D0CDB7DEB76C017A018B0182E090E0A0E04B +:205CA000B0E0F60180839183A283B3835E010894A11CB11CC601B801A7019501FEDC882323 +:205CC00039F1C601B801A70100E010E09801FDDD8823F1F0E980FA800B811C81F601878990 +:205CE000803159F088EFE8168FEFF8068FEF08078FE01807F8F281E00CC0F8EFEF16FFEFAD +:205D0000FF06F0E00F07F0E01F07A0F281E001C080E00F900F900F900F90CF91DF911F9192 +:205D20000F91FF90EF90DF90CF90BF90AF9008956F927F928F929F92AF92BF92DF92EF92D4 +:205D4000FF920F931F93CF93DF93EC01142F7093D5376093D4371F8A82E090E0A0E0B0E0C2 +:205D600088839983AA83BB831092D6371092D7371092D8371092D9371092DA378FEF9FEF10 +:205D8000DC018093D0359093D135A093D235B093D335442309F444C0453078F080E0DF914B +:205DA000CF911F910F91FF90EF90DF90BF90AF909F908F907F906F90089560E070E0CB01D3 +:205DC00040E036DC882351F3212F30E022953295307F3227207F32272C533A4CF901E2548F +:205DE000FE4F808190E08F7790700097B9F6F901E653FE4F80819181A281B381843691055F +:205E0000A105B10558F22A533E4FF901E080F18002811381E114F1040105110521F4BECF48 +:205E2000EE24FF248701C801B70140E001DC882309F4B4CF8091DF359091E035F2E080301F +:205E40009F0709F0ABCF2091E435222309F4A6CF8091E2359091E335009709F49FCF609154 +:205E6000E135662309F49ACF2A8B6C831D8670E080E090E041E050E008C0282F2F5F2D8704 +:205E800001968930910509F489CFD82E9A01082E02C0220F331F0A94E2F72617370769F759 +:205EA0006091EA357091EB356115710509F47FC080E090E06D837E838F8398878090E23570 +:205EC0009090E335AA24BB248E0C9F1CA01EB11E8B8A9C8AAD8ABE8A6090E5357090E6351C +:205EE000798E688E2091E43530E040E050E00E940A39680D791D8A1D9B1D6A8F7B8F8C8F0E +:205F00009D8F9301220F331F22953295307F3227207F322721503E4F232F3327269540E03B +:205F200050E0260F371F481F591F2E873F87488B598B8091E7359091E835009709F440C096 +:205F4000A0E0B0E0E21AF30A040B150BE80EF91E0A1F1B1F04C016950795F794E794DA941A +:205F6000D2F7E986FA860B871C8725EFE2162FE0F20620E0020720E0120758F185EFE81644 +:205F80008FEFF80680E0080780E0180730F18091003690910136A0910236B09103368A8FDB +:205FA0009B8FAC8FBD8F80E28F8B81E0F8CE6091F8357091F9358091FA359091FB357ACF66 +:205FC0008091F4359091F535A091F635B091F735B9CF8CE08F8B80E0E2CE80E18F8B81E079 +:205FE000DECECF93DF93DC01CD91DC9111971C161D06DCF41296E0E0F0E020E030E0A901BA +:20600000542F432F322F22276D9170E080E090E0262B372B482B592B3196EC17FD0781F7D3 +:20602000B901CA01DF91CF91089520E030E0A901F7CFCF93DF93FB01DC012D913C91B901FC +:206040006E5F7F4FEC01C60FD71FE60FF71FD9011196A40FB51F2115310599F02150304004 +:206060008A9192914115510519F06C91862396231197891781F320E030E0C901DF91CF9168 +:20608000089521E030E0C901DF91CF910895CF93DF93FB0120813181DC012D933C93A0816B +:2060A000B181109701F1BD01615070401296EA0FFB1FEA01CA0FDB1FA80FB91F80E09A9163 +:2060C000229130E0290F311D280F311D81E02F3F310509F008F480E02E93615070409FEFE8 +:2060E0006F3F790761F7DF91CF910895EF92FF920F931F93CF93DF938B01FC017183608313 +:206100006115710581F022E0E22EF12CE80EF91EC0E0D0E0C7018C0F9D1F0E94CE38219618 +:20612000C017D107B9F7DF91CF911F910F91FF90EF90089524E030E0FC013783268384E05D +:2061400090E0089521E0FC01208380E090E00895EF92FF920F931F93DF93CF930F92CDB7C5 +:20616000DEB77C018E010F5F1F4FC8010E94CE3889818823D1F7F7011782168280E090E0BB +:206180000F90CF91DF911F910F91FF90EF9008950F931F93DF93CF930F92CDB7DEB78C0126 +:2061A000CE010196FBD78981823070F085E090E0F8019783868325E030E0C9010F90CF91BC +:2061C000DF911F910F910895F8019181933141F0882369F481E0F801828720E030E0EDCF2B +:2061E000882359F481E0818720E030E0E6CF86E0F801828720E030E0E0CF8DE0F8018187E4 +:2062000020E030E0DACF0B96C9D780E090E00895CF93DF93EC016C897D898E559F4F66DF45 +:206220006C897D89CE018B539F4F60DF80E090E0DF91CF910895FC016489758981589F4F9D +:2062400055DF80E090E008950F931F93CF93DF938C01EC016696CE0164E070E047DFCE01A7 +:20626000C0DEF801648775878687978780E090E0DF91CF911F910F9108950F931F93CF9332 +:20628000DF938C01EC016696CE0164E070E02EDFCE01A7DEF801608B718B828B938B695F7F +:2062A0007F4F8F4F9F4F28E030E040E050E00E945F39F801358B248B2132310564F086E0F7 +:2062C00090E09783868326E030E0C901DF91CF911F910F91089520E030E0C901DF91CF91E4 +:2062E0001F910F910895BC0181E090E02BD780E090E060E070E026D780E090E061E070E063 +:2063000021C74F925F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93CF9333 +:20632000DF93EC01F62E662309F4A4C08881861709F4EEC06730C1F06E30C1F48D30B1F0A6 +:2063400005E010E0C801DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F90B8 +:206360006F905F904F900895863051F700E010E0A8E0AA2EFCE0CF2EEEE06E2E7FE0B72EFE +:2063800062E0E62E992493945AE0752E45E0D42E37E0832E23E0422E99E0592EF81691F2F3 +:2063A000873009F495C08830A8F4833009F453C0843008F03CC08130A1F1823008F454C010 +:2063C0008F2D893008F49EC081E090E08CDF58828881E4CF8B3059F08C3078F4893009F43A +:2063E00067C08A3008F47DC09F2D9B3089F081E090E079DFC8828881D1CF8D3009F452C08B +:206400008D3000F18E3009F075C09F2D9B30E9F480E090E068DFF8828881C0CF8F2D8130D8 +:2064200019F181E090E05FDFE8828881B7CF853009F444C0863090F081E090E054DF888250 +:206440008881ACCF8F2D8D3019F381E090E04BDFB8828881A3CF9F2D9430D1F281E090E05F +:2064600042DFD88288819ACF80E090E03CDF9882888194CF81E090E036DF00E010E080E0A8 +:2064800090E060E070E05ED680E090E061E070E059D60F5F1F4F0530110589F7188200E017 +:2064A00010E050CF81E090E01EDF6882888176CF80E090E018DF7882888170CF8F2D86304C +:2064C00009F4A6CF81E090E00EDFA882888166CF9F2D943009F49CCF81E090E004DFA8824E +:2064E000F5CF8F2D813009F493CF81E090E0FBDEE8829BCF8F3009F491CFF88205E010E023 +:2065000088814CCF80E090E0EEDE4882888146CF863049F08D3009F029CF81E090E0E3DEA4 +:206520008EE0888323CF81E090E0DDDE87E088831DCFCF92DF92EF92FF920F931F93CF936C +:20654000DF93EC018C010A5E1F4FC80161E070E0CDDDC88CC80161E070E0C8DDD88CC801F5 +:2065600064E070E0C3DDC8013CDD7B018C0188858C1521F0CE0108966C2DC3DEC801B70115 +:2065800023D688858D1521F0CE0108966D2DB9DE80E090E0DF91CF911F910F91FF90EF90A6 +:2065A000DF90CF9008950F931F93DF93CF930F92CDB7DEB78C01CE010196F0D5C80108966F +:2065C00069819FDE9C01009719F0F80197838683C9010F90CF91DF911F910F9108954F92F4 +:2065E0005F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93CF93DF935B014C +:206600006C01FA0138012115310509F481C080819181D90111969C938E93808191818C01AB +:206620000E5F1F4F020F131FA114B104C104D10409F45DC022E0422E512C480E591E4E0E06 +:206640005F1E0CC00115110519F0D8019E928D01A114B104C104D10409F449C0F201829016 +:206660002F01EE24FF2499240894A108B108C108D1086114710429F0A114B104C104D10451 +:2066800081F1C82DD0E0BE016170707082E090E059D580E090E060E070E054D501151105BE +:2066A00049F08ED590E00E2C02C0880F991F0A94E2F7982A80E090E061E070E043D5A1141C +:2066C000B104C104D10409F4BDCF0894E11CF11CF8E0EF16F10409F4B5CFD595C7958C2E69 +:2066E000C3CF81E090E061E070E02CD5CACFDF91CF911F910F91FF90EF90DF90CF90BF90C1 +:20670000AF909F908F907F906F905F904F9008958081918100E010E087CF2F923F924F92C7 +:206720005F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7E2 +:20674000DEB728970FB6F894DEBF0FBECDBF3C01962E29833A834B835C831E830D8317013E +:206760002601B886AF82A9A051E0C52ED12C681509F487C029813A814B815C8121153105DE +:206780004105510529F58D8D9E8DAF8DB8A10097A105B10509F097C020E030E0C90128968A +:2067A0000FB6F894DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F90D9 +:2067C0008F907F906F905F904F903F902F900895BB24EE24FF24C301692D93DD69817A81D0 +:2067E0008B819C814D815E8191018601F8DE4114510461F0C201B1014F8158851ADC41E0A0 +:20680000E42EF12C009711F0EE24FF24C114D104E9F0D3018C918F5F8C93E114F10459F0C8 +:206820002D8D3E8D4F8D58A1211531054105510511F0BA1448F1C301682D63DD8D8D9E8D10 +:20684000AF8DB8A10097A105B10591F4E114F10409F4A2CFB3948B2D81508A1508F4BBCFDE +:20686000AA2019F0AB1408F439C022E030E096CFC30161E046DD6D8D7E8D8F8D98A1A4D420 +:20688000E5CFCC24DD2476CFC30166E03ADDC30164E037DD8D8D9E8DAF8DB8A1B595A79571 +:2068A00097958795B595A795979587952D8D3E8D4F8D58A1280F391F4A1F5B1F2D8F3E8F6D +:2068C0004F8F58A3BBCFC30161E01BDD6D8D7E8D8F8D98A179D420E030E060CF23E030E05F +:2068E0005DCF8F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC018C010A5E1F4F5D +:206900006C897D89C801F2DB00D000D00F92288939894A895B89ECE5EE2EF12CEC0EFD1E5C +:2069200079E3C72ED12CCC0EDD1E6FE7A62EB12CAC0EBD1E8C859D85AE85BF85EDB7FEB795 +:2069400081839283A383B4838B858583CE01089664E08A84E2DE9C010F900F900F900F9011 +:206960000F90009711F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF9059 +:206980008F9008958F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC018C010A5E9A +:2069A0001F4FC80162E070E0A1DBC8011ADB6B017C01695F7F4F8F4F9F4F28E030E040E051 +:2069C00050E07DD4213231058CF026E030E03F832E83C901DF91CF911F910F91FF90EF90B0 +:2069E000DF90CF90BF90AF908F900895C801B9017DDB00D000D00F928C859D85AE85BF85B9 +:206A0000EDB7FEB781839283A383B4831582CE0108966BE0A7019601EE24FF24CC24DD24F3 +:206A2000AA24BB24898479DE9C010F900F900F900F900F90009769F2CACF6F927F928F92CF +:206A4000AF92BF92CF92DF92EF92FF920F931F93DF93CF930F92CDB7DEB73C01CE0101963B +:206A60009DD383010A5E1F4F298130E040E050E0295F3F4F4F4F5F4FF3E05595479537957B +:206A80002795FA95D1F7C801B90130DB00D000D00F92298130E040E050E0F30184859585F3 +:206AA000A685B785EDB7FEB781839283A383B4831582C30108966BE0EE24FF24CC24DD2436 +:206AC000AA24BB24F301818428DE9C010F900F900F900F900F90009719F0F301978386839B +:206AE000C9010F90CF91DF911F910F91FF90EF90DF90CF90BF90AF908F907F906F900895D9 +:206B00002F923F924F925F926F927F928F92AF92BF92CF92DF92EF92FF920F931F93DF93A2 +:206B2000CF9300D0CDB7DEB79A8389831A012B013901C801B901DADAC114D10419F0C601AF +:206B4000B301D4DA00D000D00F928E899F89A88DB98DEDB7FEB781839283A383B4838A8DF2 +:206B6000858389819A8164E0A2019101D6DD0F900F900F900F900F900F900F90CF91DF9193 +:206B80001F910F91FF90EF90DF90CF90BF90AF908F907F906F905F904F903F902F90089515 +:206BA0008F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC0189818131D9F114E0AF +:206BC000812E00D000D00F92488959896A897B892C893D898E010A5E1F4FBCE5EB2EF12C64 +:206BE000EC0EFD1EA9E3CA2ED12CCC0EDD1EEDB7FEB711821282138214821582CE0108967B +:206C0000AA24BB247DDF9C010F900F900F900F900F90009711F09F838E83C901DF91CF914E +:206C20001F910F91FF90EF90DF90CF90BF90AF908F9008958A84C5CF8F92AF92BF92CF9228 +:206C4000DF92EF92FF920F931F93CF93DF93EC0189818E30A9F104E0802E00D000D00F9267 +:206C6000488959896A897B892C893D898E010A5E1F4FEDB7FEB71182128213821482158248 +:206C8000CE010896EE24FF24CC24DD24AA24BB2437DF9C010F900F900F900F900F9000974F +:206CA00011F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F90089590 +:206CC0008A84CBCF8F92AF92BF92CF92DF92EF92FF920F931F93CF93DF93EC0100D000D0C0 +:206CE0000F92488959896A897B892C893D898C010A5E1F4FECE5EE2EF12CE80EF91E99E3D8 +:206D0000C92ED12CCC0EDD1E8FE7A82EB12CAC0EBD1E8C859D85AE85BF85EDB7FEB78183E5 +:206D20009283A383B4838B858583CE0108968A84E7DE9C010F900F900F900F900F9000973A +:206D400011F09F838E83C901DF91CF911F910F91FF90EF90DF90CF90BF90AF908F900895EF +:206D6000CF92DF92EF92FF920F931F93CF93DF938C016B017901B8018AD9E601288139812E +:206D8000F701A081B181AD014150504057FD38C0FD013296EE0DFF1D1196A00FB11F60E04A +:206DA00010E08291882329F1EC9001E00AC0762F660F7123B1F0E02A959587958823C1F0E9 +:206DC000000F90E080FFF8CF662389F721503040B601620F731FEB011A8162E071E071239C +:206DE00051F7702F7095E72295958795882341F7EC924150504011978FEF4F3F580789F644 +:206E0000DF91CF911F910F91FF90EF90DF90CF9008952F923F924F925F926F927F928F9242 +:206E20009F92AF92BF92CF92DF92EF92FF920F931F93DF93CF93CDB7DEB761970FB6F89421 +:206E4000DEBF0FBECDBF3C01B6E14B2E512C480E591EFC0164897589C20148D9C301089677 +:206E60009D838C83F301E45AFF4FFF83EE83C301C99699878887AFE72A2E312C260C371C4E +:206E800000D000D00F92F301208931894289538984859585A685B785EDB7FEB781839283B7 +:206EA000A383B483F3018385EDB7FEB785838C819D8164E08201EE80FF80C884D98451013E +:206EC000F30182842ADC9B838A830F900F900F900F900F90009709F087C0C3018B539F4F05 +:206EE0009D878C87FC0140815181141615060CF09DC0E0E0F0E060E000E010E0E60DF71D86 +:206F0000E953FF4F8081882351F090E09C0121703070020F131F959587958823B1F76F5F12 +:206F2000E62FF0E0E417F5074CF3CE01019636D1222717FD2095322F095F1F4F2F4F3F4F74 +:206F4000E3E03595279517950795EA95D1F71F870E879924C30188519F4F9B878A87F301AF +:206F6000EE55FF4FF98BE88B8981981608F043C08A859B856E857F85B9D8C2016A857B856D +:206F8000488959892C853D85EBDE00D000D00F92F301208931894289538984859585A68575 +:206FA000B785EDB7FEB781839283A383B483F3018385EDB7FEB785838C819D8164E0820177 +:206FC000EE80FF80C884D9845101F3018284A5DB0F900F900F900F900F90009739F4939449 +:206FE0008981981640F4C4CF8A819B81F301978386839B838A838A819B8161960FB6F8943A +:20700000DEBF0FBECDBFCF91DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F9093 +:207020006F905F904F903F902F90089500E010E07CCFCF93DF93EC01188219821A821B820E +:207040001C821D821F821E821B86188681E089878A87188A198A1A8A1B8A1D8A1C8A1C8674 +:207060001D861E861F86CE01089660E04AD98E839F83DF91CF910895CF93DF93EC012E8144 +:207080003F812115310519F48881882321F0C901DF91CF910895CE01019680D08A819B81DE +:2070A000AC81BD810196A11DB11D8A839B83AC83BD83E981E83150F084E090E09F838E83DE +:2070C00024E030E0C901DF91CF910895F0E0EE0FFF1FE851FD4F0190F081E02DCE01099579 +:2070E0002E813F81D4CF0F931F93DF93CF93CDB7DEB7CB50D1400FB6F894DEBF0FBECDBFCA +:207100008E010F5F1F4FC80194DF2F8138852115310569F0C901C55FDE4F0FB6F894DEBF8D +:207120000FBECDBFCF91DF911F910F9108958981882381F7C801A0DF2F81388521153105EB +:20714000B1F3E8CF8130910551F08230910561F0009721F46115710571F4429808956115C9 +:20716000710539F0439A08956115710531F0459A089543980895429A08954598089580E0A2 +:2071800090E060E070E0DEDF80E090E061E070E0D9CF9093DC378093DB370895CF93DF935D +:2071A000EC01E091DB37F091DC37309729F009958883DF91CF9108951882DF91CF910895CE +:2071C00081E0349B80E00895AF92BF92CF92DF92EF92FF920F931F935B016C0116161706A6 +:2071E0001806190674F4EE24FF248701C8DF0894E11CF11C011D111DEA14FB040C051D0564 +:20720000ACF31F910F91FF90EF90DF90CF90BF90AF900895629FD001739FF001829FE00D95 +:20722000F11D649FE00DF11D929FF00D839FF00D749FF00D659FF00D9927729FB00DE11D58 +:20724000F91F639FB00DE11DF91FBD01CF0111240895AA1BBB1B51E107C0AA1FBB1FA617ED +:20726000B70710F0A61BB70B881F991F5A95A9F780959095BC01CD010895A1E21A2EAA1BED +:20728000BB1BFD010DC0AA1FBB1FEE1FFF1FA217B307E407F50720F0A21BB30BE40BF50BAB +:2072A000661F771F881F991F1A9469F760957095809590959B01AC01BD01CF01089597FB0C +:2072C000092E05260ED057FD04D0D7DF0AD0001C38F450954095309521953F4F4F4F5F4F5F +:2072E0000895F6F790958095709561957F4F8F4F9F4F08950790F691E02D09949111089591 +:2073000081568A5108F4805285580895FC0105900020E9F7809590958E0F9F1F0895FB01B3 +:20732000DC0104C08D910190801921F441505040C8F7881B990B0895FB01DC0102C001905F +:207340000D9241505040D8F70895FB01DC014150504030F08D910190801919F40020B9F7C2 +:20736000881B990B0895FB01DC014150504048F001900D920020C9F701C01D924150504056 +:20738000E0F708950F931F93DF93CF93CDB7DEB72E970FB6F894DEBF0FBECDBF0D891E89EF +:2073A0008F89988D26E02C831A83098397FF02C080E090E801979E838D839E01255E3F4F09 +:2073C000CE010196698D7A8DA90119D04D815E8157FD0AC02F813885421753070CF49A0131 +:2073E000020F131FF80110822E960FB6F894DEBF0FBECDBFCF91DF911F910F9108952F9236 +:207400003F924F925F926F927F928F929F92AF92BF92CF92DF92EF92FF920F931F93DF9329 +:20742000CF93CDB7DEB72C970FB6F894DEBF0FBECDBF6C011B018A01FC0117821682838181 +:2074400081FFC4C12E010894411C511CF6019381F10193FD859193FF81911F01882309F483 +:20746000B1C1853239F493FD859193FF81911F01853221F490E0B601F5D1E8CFEE24FF24A7 +:2074800020E02032B0F48B3269F08C3228F4803251F0833271F40BC08D3239F0803349F456 +:2074A00021602CC02260246029C0286027C0206125C027FD2CC0382F30533A3098F426FF86 +:2074C00008C08E2D880FE82EEE0CEE0CE80EE30E15C08F2D880FF82EFF0CFF0CF80EF30E36 +:2074E00020620CC08E3221F426FD6CC1206406C08C3611F4206802C0883649F4F10193FD41 +:20750000859193FF81911F01882309F0BACF982F9554933018F09052933028F40C5F1F4F4F +:20752000FFE3F9830DC0833631F0833771F0833509F05CC021C0F801808189830E5F1F4F9C +:20754000420171E0A72EB12C15C062E0662E712C600E711EF8018080918026FF03C06E2D13 +:2075600070E002C06FEF7FEFC4012C8770D15C0183012C852F7716C052E0652E712C600E96 +:20758000711EF8018080918026FF03C06E2D70E002C06FEF7FEFC4012C874ED15C012C854C +:2075A0002068830123FD1EC007C080E290E0B6012C8758D1FA942C858F2D90E0A816B906AD +:2075C000A0F310C0F40127FD859127FF81914F0190E0B6012C8746D12C85F110FA940894C4 +:2075E000A108B108A114B10469F7E9C0843611F0893641F527FF08C0F80160817181828149 +:2076000093810C5F1F4F09C0F80160817181882777FD8095982F0E5F1F4F4FE6B42EB22223 +:2076200097FF09C090958095709561957F4F8F4F9F4FF0E8BF2AA2012AE030E03FD1782EE8 +:20764000741844C0853731F43FEEB32EB2222AE030E025C099EFB92EB2228F36C1F0803768 +:2076600020F4883509F0AEC00DC0803721F0883709F0A8C002C020E1B22AB4FE0BC084E09D +:20768000B82A08C0B4FE09C0E6E0BE2A06C028E030E005C020E130E002C020E132E0B7FED9 +:2076A00008C0F80160817181828193810C5F1F4F07C0F8016081718180E090E00E5F1F4F08 +:2076C000A201FCD0782E7418FFE7BF22B6FE0BC02EEFB2227E1438F4B4FE07C0B2FC05C028 +:2076E0008FEEB82202C0A72C01C0AE2C8B2D90E0B4FE0DC0FE01E70DF11D2081203319F45A +:20770000E9EEBE2209C0A394B2FE06C004C086789070009709F0A3948B2C9924B3FC13C0BD +:20772000B0FE0EC0AF1428F4E72CEF0CEA18AF2C07C0E72C05C080E290E0B60193D0A39441 +:20774000AF14C8F304C0AF1410F4FA1801C0FF2484FE0EC080E390E0B60184D082FE1DC09F +:2077600081FE03C088E590E010C088E790E00DC0C40186789070009781F081FC02C080E202 +:2077800001C08BE2B7FC8DE290E0B6016BD005C080E390E0B60166D0EA947E14C8F37A94D9 +:2077A000F201E70DF11D808190E0B6015BD07720B1F705C080E290E0B60154D0FA94FF2023 +:2077C000C9F744CEF6012681378102C02FEF3FEFC9012C960FB6F894DEBF0FBECDBFCF9140 +:2077E000DF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F904F903F9066 +:207800002F900895F999FECF92BD81BDF89A992780B50895262FF999FECF92BD81BDF89A29 +:20782000019700B4021639F01FBA20BD0FB6F894FA9AF99A0FBE0895FC0105906150704030 +:207840000110D8F7809590958E0F9F1F0895FC016150704001900110D8F7809590958E0F70 +:207860009F1F08950F931F93CF93DF938C01EB018B8181FF1BC082FF0DC02E813F818C81DB +:207880009D812817390764F4E881F9810193F983E88306C0E885F985802F0995009731F4DB +:2078A0008E819F8101969F838E8302C00FEF1FEFC801DF91CF911F910F910895FA01AA27AF +:2078C000283051F1203181F1E8946F936E7F6E5F7F4F8F4F9F4FAF4FB1E03ED0B4E03CD03C +:2078E000670F781F891F9A1FA11D680F791F8A1F911DA11D6A0F711D811D911DA11D20D037 +:2079000009F468943F912AE0269F11243019305D3193DEF6CF010895462F4770405D419322 +:20792000B3E00FD0C9F7F6CF462F4F70405D4A3318F0495D31FD4052419302D0A9F7EACF95 +:20794000B4E0A6959795879577956795BA95C9F700976105710508959B01AC010A2E0694CE +:207960005795479537952795BA95C9F7620F731F841F951FA01D089517E000E0C4E6D7E0BC +:2079800040E005C022974109FE014BBFB3DCC636D1074007B9F7F894FFCF2E2E0053656CC2 +:2079A000656374204469736B006E6F20696D6167652066696C657320666F756E640001036D +:2079C0000507090E10121416181C1E696E636F6D706C657465207772697465006261642024 +:2079E000736563746F7220256420666F722074256400627566206C6F636B65642025642F23 +:207A000025643A256400636865636B73756D206661696C757265203000636865636B737589 +:207A20006D206661696C757265203100636865636B73756D206661696C7572652032006370 +:207A40006865636B73756D206661696C0043504C44204669726D77617265202564002564C8 +:207A6000002575006669726D776172652E7876660053442072656164206572726F7220527E +:207A800000526573756C743A207375636365737300526573756C743A206572726F722025CC +:207AA000640053442072656164207374617274206572726F7200534420726561642065722D +:207AC000726F7220440077722077726F6E6720747261636B2025642F25640052657665721F +:207AE0007465642074726B20253032642020200053442072656164206572726F7220570059 +:207B000053442077726974655374617274206661696C005344207772697465206572726FFF +:207B20007200534420777269746553746F70206661696C0053617665642074726B202530B6 +:207B4000326420696E20256C7520200053442063617264206572726F722025643A2564002B +:207B6000253032640025642000D5AAAD0000000000000000000000008A01AD01D8010D0224 +:207B80004E02A2301B311D35713424319A309A3003313D316236083109371C361C361C36EE +:127BA000D035D035D035D332C830C830C234A830993236 +:020000040001F9 +:20EFF800DDDDDDDD0001000097C00000B2C00000B0C00000AEC00000ACC00000AAC0000007 +:20F01800A8C00000A6C00000A4C00000A2C00000A0C000009EC000009CC000009AC00000D0 +:20F0380098C0000096C0000094C0000092C0000090C000008EC000008CC000008AC0000030 +:20F0580088C0000086C0000084C0000082C0000080C000007EC000007CC000007AC0000090 +:20F0780078C0000076C0000074C0000072C0000070C000001E051E1F150A0E11111F110E87 +:20F098001F15151F05050E151D1F041F111F1108100F1F041B1F10101F061F1F0E1F0E11D0 +:20F0B8000E1F05020010001F0D16121509011F010F101F0718071F0C1F000000031C030091 +:20F0D8000A004552524F525A58464C41534858495358454D5054590046454D555142494E32 +:08F0F800584E4F5458464F5585 +:20F100004E4400464C415348494E475846454D555142494E5851515100464C4F50505958E5 +:20F12000454D5558424F4F544C4F41444552000011241FBECFEFD0E4DEBFCDBF11E0A0E087 +:20F14000B1E0E8EEFFEF01E00BBF02C007900D92AA30B107D9F712E0AAE0B1E001C01D92D8 +:20F16000A733B107E1F7DBD03DC74ACF249A259A279A2E9A089588EC3197319731970000EE +:20F180008A95D1F7089502D02C9801C02C9A8FEF98E087FD2D9A87FF2D98880F1E998395DC +:20F1A0002F9A2F989A95A9F70895FB018BBF83E080935700E8958091570080FDFCCF81E1B1 +:20F1C00080935700E89508950F921F928BBFFB01DA0190E80D901D9081E080935700E8952E +:20F1E00032969A95B9F7FB0185E080935700E8958091570080FDFCCF81E180935700E89527 +:20F200001F900F9008955E9808955E9A0895A1E0B0E0ECE0F9EFB8C68983B8DF2A98898129 +:20F22000B7DF2A9A2196E2E0CBC6A2E0B0E0EAE1F9EFAAC66A838983E6DF89818068E7DFBF +:20F240006A81862F8064E3DF2296E2E0B9C6CF93DF93DBDFC8EFD1E080E0D9DF2197E1F7D1 +:20F26000DF91CF910895EF92FF920F931F93CF93DF938C01CADF1FC023E0829FC0011124B8 +:20F280000F5F1F4FEC01C753D0412CECE22E2FEEF22EE80EF91ECE01AA2797FDA095BA2FB6 +:20F2A000ABBFFC018791880FB2DF2196CE15DF0591F780E0ACDFC801AA2797FDA095BA2F6A +:20F2C000ABBFFC0187918823B9F6CDB7DEB7E6E073C61F93209A229A569A48DF2A98289A7A +:20F2E00018EC49DF1150E9F7289818EC44DF1150E9F7289A18EC3FDF1150E9F784DF81E28E +:20F3000086DF8FEB84DF84E182DF80E280DF8CE07EDF80E060E089DF9ADF1F910895A2E00B +:20F32000B0E0E4E9F9EF29C65C9A599A5A9A8FE493EC0197F1F700C00000499956C04C99AD +:20F3400054C0239AC6DF89E191EF8DDF80E062E06CDF8DE091E0A0D280E091E0ACD38823A9 +:20F3600009F03AC083E091EF7EDFEE24FF2487016E010894C11CD11C88E0B82EC801B701F9 +:20F3800014DF87E391E06FEF70E040E051E023D687E391E060E071E0A601ECD489819A81AF +:20F3A000009729F0C801B70147E351E00DDF85B18B2585B980E091E0A0E0B0E0E80EF91EC3 +:20F3C0000A1F1B1F90E0E91690EFF90691E0090790E0190799F603C080EF90EF44DF499B85 +:20F3E000FECF4C9BFCCF4A9BFACF80E090E0FC0125913491AFEF2F3F3A0711F0FC010995AF +:20F4000068DF80E060E011DF8AED90EF2CDFFFCFDF92EF92FF920F931F93182F042FF52ED2 +:20F42000E62ED72E87FF08C087E740E050E0BA01EFDF8230E0F41F77A6DE812FA9DE8D2D8D +:20F44000A7DE8E2DA5DE8F2DA3DE802FA1DE103421F0183421F081E003C085E901C087E80A +:20F4600097DE1AE094DE87FF02C01150D9F71F910F91FF90EF90DF900895A5E0B0E0E2E4ED +:20F48000FAEF7CC573DE04E676DE0150E9F70AE07DDE0150E9F780E440E050E0BA01B8DF06 +:20F4A000813009F067C088E44AEA51E060E070E0AFDF8130D1F58E010F5F1F4F45E0C42E93 +:20F4C000D12CCC0EDD1E780162DEF70181937F01EC15FD05C9F78B81813009F04BC08C8184 +:20F4E0008A3A09F047C008C046DE0894E108F108E114F10429F43EC030E1E32E37E2F32E7D +:20F5000089EE40E050E060E070E482DF882361F73DC03DDEF80181938F01EC15FD05C9F7B4 +:20F52000898186FF25C09CE026C089EE40E050E0BA016EDF823020F492E029EEE22E03C004 +:20F5400091E081E4E82E00E117E208C09D8313DE015010409D810115110561F08E2D40E0F5 +:20F5600050E0BA019D8354DF9D81882379F717C094E001C090E090930A019D8307DE81E004 +:20F580009D81911180E02596E8E014C58AE740E050E0BA013DDF882309F4BBCFEBCF80E506 +:20F5A00040E052E060E070E09D8332DF9D81882309F7E1CFA1E0B0E0EFEDFAEFDDC46C01DB +:20F5C000590180910A0183FD07C0E9E0440F551F661F771FEA95D1F781E51ADF882391F5EC +:20F5E00050E4E52E5CE9F52ED2DD8F3F39F40894E108F108E114F104B9F724C08E3F11F5E3 +:20F60000EE24FF24EA18FB0882E092E0E80EF91EE01AF10AA114B10429F0B9DD0894A1087C +:20F62000B108F8CFB4DDF60181936F0101501040C9F7ADDD0894E108F108E114F104C9F72B +:20F6400080E001C081E08983A1DD89812196EAE0AFC4CF93DF93C0910B01D0910C0162504F +:20F660007040804090402E813F81488559852250304040405040621773078407950780F4B0 +:20F680002A8130E040E050E02ED49B01AC018A899B89AC89BD89280F391F4A1F5B1F03C02D +:20F6A00020E030E0A901B901CA01DF91CF910895CF93DF93EC01E0910B01F0910C01198237 +:20F6C00018826C817D818E819F81613071058105910551F126813781408551856217730724 +:20F6E0008407950708F5611571058105910539F42081233021F466857785808991896887AF +:20F7000079878A879B87611571058105910511F0A0DF04C066857785808991896C877D8769 +:20F720008E879F8780E001C081E0DF91CF910895A4E0B0E0EDE9FBEF25C4DC01CB01E091C8 +:20F740000B01F0910C0182309105A105B10508F452C0268137814085518582179307A40785 +:20F76000B50708F048C02081223021F0233009F042C01CC0492F5A2F6B2F77270285138547 +:20F7800024853585400F511F621F731F9C013070220F331FCE01019602E010E00BDF8823A7 +:20F7A00051F529813A8140E050E029C0AC01BD0127E076956795579547952A95D1F7028516 +:20F7C000138524853585400F511F621F731F9C012F773070220F331F220F331FCE0101960D +:20F7E00004E010E0E7DE882331F429813A814B815C815F7004C021E030E040E050E0B901E4 +:20F80000CA012496E4E0DAC3A0E0B0E0E9E0FCEFB1C3F82EE92E5A016B012EEF31E002E0B6 +:20F8200010E0C8DE882369F58F2CE4014E019E2CE401888199812AEA8535920721F58F2D2F +:20F840009E2DB601A50126E330E0B4DE882331F48881998121E486349207B9F08F2D9E2D5A +:20F86000B601A50122E530E002E010E0A3DE882371F481E02881398191E42634390741F4A9 +:20F8800004C083E005C082E003C080E001C081E0CDB7DEB7ECE08AC3A8E2B0E0E1E5FCEFD8 +:20F8A00065C37C0110920C0110920B01009709F4F8C0E3DD80FDF7C06E010894C11CD11C31 +:20F8C000C60140E050E0BA019FDF8130C9F4C60140E050E0BA012EEB31E000E110E06ADE55 +:20F8E000882309F0E2C08D81882309F4E0C089849A84AB84BC84C601B501A40185DF03C089 +:20F90000882499245401833009F4CFC0882309F0CEC06E010894C11CD11CC601B501A401C1 +:20F920002DE030E004E210E045DE882309F0BDC0D60119966D917C911A9780E090E0611508 +:20F9400071058105910521F4688D798D8A8D9B8D2C8130E040E050E0C6D26DA37EA38FA3BE +:20F9600098A7F6014180528066247724480C591C6A1C7B1CD7011A964D925D926D927C9250 +:20F980001D97E9811296EC93D60114964D915C911597D70115965C934E931497D6011696A9 +:20F9A0006D917C91179780E090E0611571058105910521F46C897D898E899F8904E0569598 +:20F9C00047950A95E1F74A01AA24BB24D60111960D911C91129720E030E0601B710B820BD6 +:20F9E000930B2DA13EA14FA158A5621B730B840B950B681979098A099B092E2F30E040E0DE +:20FA000050E090D22E5F3F4F4F4F5F4FD70116962D933D934D935C931997273FBFE03B0713 +:20FA2000B0E04B07B0E05B0708F441C0273FEFEF3E07E0E04E07E0E05E0710F482E001C00B +:20FA400083E0D7018C93833029F488A199A1AAA1BBA108C08DA19EA1AFA1B8A5840D951D4D +:20FA6000A61DB71DF70186879787A08BB18B480C591C6A1C7B1C2DA13EA14FA158A5420E95 +:20FA8000531E641E751ED70152964D925D926D927C92559711961C921197F0920C01E0925B +:20FAA0000B0180E005C082E003C081E001C087E0A896E0E177C2ACE3B0E0E0E6FDEF54C248 +:20FAC000C0900B01D0900C01C114D10409F446C1F60111829E012F5F3F4F388B2F877C0174 +:20FAE000FC01208101962032D1F32F3209F47C01198A1A8A1B8A1C8AF7018081813240F46E +:20FB0000CE010D96D5DD1D8E882309F4F7C029C190E2892E8DE0482E512C4C0E5D1EBDE1D1 +:20FB20006B2E712C6C0E7D1EA8E22A2E312C2C0E3D1EEF85F889DF01CF010B9601C08D9280 +:20FB4000A817B907E1F790E0992428E0D701A90DB11D8C9193948132C0F08F32B1F08E32F4 +:20FB600011F0921738F0283081F48E3271F498E02BE0ECCF382F31563A3108F48052DF017C +:20FB8000A90FB11D8C939F5FE1CF91E0813208F090E09387C2018CDD882309F086C0498D80 +:20FBA0005A8D6B8D7C8D2D853E852F703070F5E0220F331FFA95E1F7C30100E210E0FADC7E +:20FBC000882309F0D1C08D8D882309F4CFC088A583FD0BC0F301AF85B889E215F30509F4D2 +:20FBE0006EC091918D919817C1F3A0900B01B0900C010D851E850F5F1F4F09F4B7C0898D10 +:20FC00009A8DAB8DBC8D0097A105B10509F4AEC098012F7030702115310509F043C0019607 +:20FC2000A11DB11D898F9A8FAB8FBC8F6D897E898F89988D611571058105910541F4F50105 +:20FC4000848195810817190708F090C02BC0F501228130E021503040A801E4E05695479559 +:20FC6000EA95E1F72423352321153105D9F460DD623071058105910508F476C0F501268125 +:20FC8000378140855185621773078407950708F06DC06D8B7E8B8F8B988FDBDC698F7A8FD8 +:20FCA0008B8F9C8F1E870D877ACF833009F059C0EF85F8899385992309F45AC052C0EF8552 +:20FCC000F88983858823D1F488A584FF51C0E90CF11CF30184899589A0E0B0E0DC0199279C +:20FCE0008827228D338D40E050E0822B932BA42BB52B898B9A8BAB8BBC8B1BCF8D8D882317 +:20FD000079F188A584FD2CC0BE01635E7F4FFB0184899589A0E0B0E0DC0199278827228D5F +:20FD2000338D40E050E0822B932BA42BB52BF601868F978FA0A3B1A3FB01848D958DA68D6E +:20FD4000B78DF601828F938FA48FB58F168A178A108E118E81E0818380E003C086E001C091 +:20FD600083E0EC96E2E11CC181E0FBCF83E0A0CF84E0F7CFA0E0B0E0EFEBFEEFF7C03C010C +:20FD80007B014A01C0910B01D0910C01FA0111821082209709F4A0C0898180FF9FC08A8D9E +:20FDA0009B8DAC8DBD8D2E893F89488D598D821B930BA40BB50B9B0140E050E08217930795 +:20FDC000A407B50708F47C015301412C72E0572E7AC08E899F89A88DB98D9C01AD013170CB +:20FDE000407050702115310541055105C1F59C01AD0169E056954795379527956A95D1F72B +:20FE0000CA80CA94C222C1F40097A105B10529F46E8D7F8D88A199A105C06AA17BA18CA10E +:20FE20009DA186DC623071058105910508F451C06AA37BA38CA39DA36AA17BA18CA19DA1C5 +:20FE400008DC611571058105910509F442C06C0D711D811D911D6EA37FA388A799A72E890B +:20FE60003F893170C201821B930B67018E159F0508F46C016114710419F480E090E001C07B +:20FE8000C5014EA15FA168A579A5860193DB882301F5960140E050E08E899F89A88DB98D4B +:20FEA000820F931FA41FB51F8E8B9F8BA88FB98FAC0CBD1CEC18FD08F401808191818C0D6B +:20FEC0009D1D91838083E114F10409F082CF80E006C0198281E003C086E001C085E0CDB728 +:20FEE000DEB7E0E15FC0629FD001739FF001829FE00DF11D649FE00DF11D929FF00D839F4E +:20FF0000F00D749FF00D659FF00D9927729FB00DE11DF91F639FB00DE11DF91FBD01CF01CC +:20FF200011240895A1E21A2EAA1BBB1BFD010DC0AA1FBB1FEE1FFF1FA217B307E407F50796 +:20FF400020F0A21BB30BE40BF50B661F771F881F991F1A9469F760957095809590959B01CF +:20FF6000AC01BD01CF0108952F923F924F925F926F927F928F929F92AF92BF92CF92DF927D +:20FF8000EF92FF920F931F93CF93DF93CDB7DEB7CA1BDB0B0FB6F894DEBF0FBECDBF09945F +:20FFA0002A88398848885F846E847D848C849B84AA84B984C884DF80EE80FD800C811B81CF +:20FFC000AA81B981CE0FD11D0FB6F894DEBF0FBECDBFED010895DC0101C06D934150504060 +:12FFE000E0F70895F894FFCF66656D752E62696E00002D +:040000050001F00006 +:00000001FF diff --git a/source-1.0L-F11/firmware/readme.txt b/source-1.0L-F11/firmware/readme.txt new file mode 100755 index 0000000..8e480df --- /dev/null +++ b/source-1.0L-F11/firmware/readme.txt @@ -0,0 +1,24 @@ +To update the Xilinx CPLD firmware: + +1. Copy firmware.xvf to the root directory of your SD card, and insert it into Floppy Emu. +2. Hold down the PREV and NEXT buttons. +3. Press and release the RESET button. +4. Follow the on-screen prompts. + + +To update the microcontroller application software: + +If you have the SD bootloader already installed: +1. Copy femu.bin to the root directory of your SD card, and insert it into Floppy Emu. +2. Hold down the PREV and SELECT buttons. +3. Press and release the RESET button. +4. Follow the on-screen prompts. + +If you don't have the SD bootloader installed: +1. Use your AVR ISP programmer to flash floppyemu.hex to the microcontroller. + +If you want to install the SD bootloader: +1. Use your AVR ISP programmer to flash merged.hex to the microcontroller. +2. Use the ISP programmer to set the BOOTRST fuse to 1 (on), and the BOOTSZ fuse to 2048W_F800. (Fuses should be Extended: 0xFF, High: 0xDA, Low: 0xBF) + + diff --git a/source-1.0L-F11/instructions.docx b/source-1.0L-F11/instructions.docx new file mode 100755 index 0000000..ffb3f7a Binary files /dev/null and b/source-1.0L-F11/instructions.docx differ diff --git a/source-1.0L-F11/license.txt b/source-1.0L-F11/license.txt new file mode 100755 index 0000000..0963a45 --- /dev/null +++ b/source-1.0L-F11/license.txt @@ -0,0 +1,3 @@ +Floppy Emu was designed and developed by Steve Chamberlin, "Big Mess o' Wires", copyright 2013. The source files, schematics, and related materials are licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported license. To learn more about the CC BY-NC 3.0 license, see http://creativecommons.org/licenses/by-nc/3.0/ + +You're free to build a Floppy Emu for personal use, or adapt and share the design for other non-commercial projects. Please do not build a batch of Floppy Emus and sell them on eBay. If you need a commercial license or another non-creative-commons license, contact steve@bigmessowires.com. diff --git a/source-1.0L-F11/~$bom.xlsx b/source-1.0L-F11/~$bom.xlsx new file mode 100755 index 0000000..aa47638 Binary files /dev/null and b/source-1.0L-F11/~$bom.xlsx differ diff --git a/source-1.0L-F11/~$cost.xlsx b/source-1.0L-F11/~$cost.xlsx new file mode 100755 index 0000000..aa47638 Binary files /dev/null and b/source-1.0L-F11/~$cost.xlsx differ