mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			FluxEngine
			...
			FluxEngine
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ebcb9c4bb0 | ||
|  | 2520834b18 | ||
|  | a1f3087046 | ||
|  | e9670e205e | ||
|  | 658e2b7295 | ||
|  | 7b4a8d6de2 | ||
|  | e8f7b51aef | ||
|  | 9d6bc57a5f | ||
|  | 73766f92b4 | ||
|  | 80badf3b54 | ||
|  | 116529f85a | ||
|  | 5a2b2bc07a | ||
|  | 41070395c0 | ||
|  | 4304d1eede | ||
|  | 46f1b0aef4 | ||
|  | c266779433 | 
| @@ -17,24 +17,24 @@ | ||||
| :400400009B1A04218DF81910ADF81A30FEE20220FFF784FE4FF000090DF1180A4FF480780027C8EB0903DA1907F80A200137402FF9D10220FFF772FE3A465146022001F003 | ||||
| :4004400095F8B8F10108EBD109F10109B9F1400FE4D16F4BAEE294F82A0001F07BFF606AFFF7ECFE012001F087FF01F0D9FF694BDFF8A8811A78002742F004021A701A7898 | ||||
| :4004800042F001021A701A7802F0FE021A701A7802F0FE021A7001F0C7FF0220FFF73EFE41F6FF734FF480420121022001F024FF84F8680000F094FD08F807000137102F6D | ||||
| :4004C000F8D1DFF85CA100270AF15D081FFA88F90137102F14BF3A4600221AF8010F22440623127D402100F0AFFD4A4646F24C419AF8000000F0BAFD09F14009102F1FFAEC | ||||
| :4004C000F8D1DFF85CA100270AF15D081FFA88F90137102F14BF3A4600221AF8010F22440623127D402100F0AFFD4A4646F24B419AF8000000F0BAFD09F14009102F1FFAED | ||||
| :4005000089F9E5D14448FFF761FE00237373637B002BFCD000271422394606A87773DFF8049102F03EF84023099338464FF0FF337760CDF82090B360377301F01DFF012097 | ||||
| :4005400001F060FF736896F868003344197D00F0FFFC96F8680000F0BDFC012196F8680000F090FC636813B96B7B002BFAD0002794F82BA0A76094F80CB0BBF1000F6CD1F8 | ||||
| :4005800000F0C0FD6B7B43B1BAF1010A85F80DB003D162E02B7B002B5FD1A26863689A42F8D04FF0000BA36806A808EB83135B440693CBF14003079300F054FA079B0137BF | ||||
| :4005C000C3F140039B44099B5FFA8BFB002B34D1022000F0AFFF012826D0637B002B3CD12B7B002BF4D038E0910000000D010000A5000000D90000008081FF1F932E0000D3 | ||||
| :40060000A62E0000A881FF1FB02E0000282E00002A2E00009C640040BF2E00009481FF1F9381FF1FF085FF1F4022BE49022000F09DFF4023CDF820900993BBF13F0FB2D9DE | ||||
| :40060000A62E0000A881FF1FB02E0000282E00002A2E00009B640040BF2E00009481FF1F9381FF1FF085FF1F4022BE49022000F09DFF4023CDF820900993BBF13F0FB2D9DF | ||||
| :40064000A268B94B01321340002BBEBF03F1FF3363F00F030133A3608DE7002001F0D2FE042194F8680000F07FFC94F8680000F08BFC0028F9D106A800F028FA0220FFF76E | ||||
| :400680004DFDDDF82480B8F1400F06D0C8F1400292B2A449022000F069FF099A32F0400203D11146022000F061FF0220FFF736FDFFF780FD237B33B19C48FFF787FD02209F | ||||
| :4006C000FFF7ACFD06E09A4B05A81B88ADF81430FFF792FD627B3946237B9648CDF80080FFF774FDA7E1E76A17F03F0701D003209FE195F82A0001F02DFE012001F042FE8F | ||||
| :4007000001F08EFE8C4BDFF834821A7802F0FB021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7001F07DFE686AFFF784FD01214FF4804341F6FF7208468D | ||||
| :4007400001F026FE85F8680000F04AFC08F807000137102FF8D1DFF8E891002709F15D031FFA83F803930137102F14BF3A46002219F8010F22440523127D402100F064FC2C | ||||
| :40078000414646F24A4299F8000000F06FFC08F14008102F1FFA88F8E5D1F36A00279B09142239464FF0FF3806A877600293C6F80880377301F0F5FE402301200993B946D3 | ||||
| :40078000414646F24E4299F8000000F06FFC08F14008102F1FFA88F8E5D1F36A00279B09142239464FF0FF3806A877600293C6F80880377301F0F5FE402301200993B946CF | ||||
| :4007C00000F012FFBA466268574B01321340002BBCBF03F1FF3363F00F03A168B8BF01338B4200F08F80BAF1000F07D0237B002B40F0A8806B7B002B40F0A480079B002B71 | ||||
| :4008000034D1B9F1000F0BD07F2246495A540133402BFAD10691079328E0BAF1000F06D1012000F087FE01288346F6D107E0237B002B40F087806B7B002BF1D082E0394921 | ||||
| :40084000FFF774FC8146374B07905846069300F0CBFEB9F13F0F07F1010706DD029BDB1BD3F1000949EB030900E0D946079BDBB16368039A06A802EB8312099BC3F1400367 | ||||
| :400880001344089300F031F9099B6BB96A68264B01321340002BBEBF03F1FF3363F00F030133636040230993A36801332AD16B680F2B27D14FF00008C5F8088001F096FD23 | ||||
| :4008C00085F80C80AB6895F868002B44197D00F03FFB95F8680000F0FDFA012195F8680000F0D0FA85F80D80637B002BFCD04FF00008012086F80D8001F032FD404601F022 | ||||
| :4009000041FD02E0BAF1000F05D0237BD3B96B7BC3B94FF0010AA36843453FF454AFD5F8088050E7F085FF1F0F000080C42E00002C2E0000DE2E00009A6400409481FF1FF2 | ||||
| :4009000041FD02E0BAF1000F05D0237BD3B96B7BC3B94FF0010AA36843453FF454AFD5F8088050E7F085FF1F0F000080C42E00002C2E0000DE2E00009E6400409481FF1FEE | ||||
| :400940009381FF1F01F058FD012001F01BFD002001F006FD042194F8680000F005FB94F8680000F011FB0028F9D196F8680000F09FFAB9F1000F16D1029BBB420ADD012015 | ||||
| :4009800000F0D8FD01288046F6D12E49FFF7CEFB3F2803DC012000F061FE04E0404600F023FE0137E8E7FFF705FC237B0BB102203FE0254B1B8805A8ADF8143027E094F880 | ||||
| :4009C0002A0001F0C7FC606AFFF738FC1F48FFF7FDFB00236373637B002BFCD0012001F0BFFC00237373637B002BFCD0002001F0B7FC1748FFF7EAFB164B04E00020E073A1 | ||||
| @@ -46,12 +46,12 @@ | ||||
| :400B400081601370C368013BC360CFE730BD0000F8B572B6634B61221A70A3F5F06301221A80192406229C7083F88022522203F5C0731A705C4B5D4A1B785D4EDBB2137059 | ||||
| :400B800040F618025B4B00251A8041F2512223F8022C33784FF4F07003F0010343EA450501F036FC013C05F0030521D0032DF0D1514B4FF480721A8007221A704F4A0024BB | ||||
| :400BC00048211470917002221C705C7103F8032C4B4A4C4D1378062643F001031370414B01221A70484A137843F02003137000E0FEE706FB045300219A881868013401F08C | ||||
| :400C0000D0FC082CF5D180224049414801F0BEFC404D4148002450F8041F04F1105303F1400221F0FF064133C9B20B4452005B0002329A4206D012F8027C12F801EC07F8F7 | ||||
| :400C0000D0FC082CF5D180224049414801F0BEFC404D4148002450F8041F04F1105303F1420221F0FF064333C9B20B4452005B0002329A4206D012F8027C12F801EC07F8F3 | ||||
| :400C400006E0F5E7A8420C44E5D1344B00221A60334B34491A68344B344C1A60344A137843F002031370137C43F002031374314B1A7842F040021A700A7842F010020A7053 | ||||
| :400C80002D4A07CA03C42D49228008682C4A28341060097911712B4A07CA03C422802A4AE83C07CA03C42280284A083407CA03C4274922800A78A4F6785442F008020A70E0 | ||||
| :400CC000244A01F5AA5112780C31D2B202F00700120908704A70204A442111700FCB07C42380F8BD004800400F010049A1460040254200402242004004400040064000405A | ||||
| :400D0000A2430040172F0000E846004054050048000C01407C000048FCFFFF47007600400C060048C243004008760040C051004003500140A0430040D4050048E00500487E | ||||
| :400D4000CB510040E8050048F40500480006004822430040CF0100497658004008B501F0E9FB03680C2B00D1FEE7FEE7084908B50B68084A1844821A802A01DC086005E019 | ||||
| :400D0000A2430040172F0000E8460040A4050048800A014080000048FCFFFF47007600405C060048C243004008760040C051004003500140A04300402406004830060048BA | ||||
| :400D4000CB51004038060048440600485006004822430040CF0100497658004008B501F0E9FB03680C2B00D1FEE7FEE7084908B50B68084A1844821A802A01DC086005E027 | ||||
| :400D800001F0D8FB0C2303604FF0FF33184608BDCC80FF1F1087FF1F80B51148114B0025C0B1A3F1100192C922460439161BB74204D051F8046F42F8046BF7E7114653F822 | ||||
| :400DC000046C8C1AA64202D041F8045BF9E701381033E5E701F0B4FBFFF782FAFEE700BF01000000D8300000124A134B10B51A60124A134C1368134843F4007313600023DA | ||||
| :400E0000032B98BF54F823204FEA830188BF0E4A0133302B4250F3D10C4B1A780C4B1A700C4B084A1A60FFF793FEBDE8104000F013B800BF0004FA050CED00E014ED00E0BD | ||||
| @@ -136,13 +136,13 @@ | ||||
| :4021C000FFF77EBE0D4B9B78012B14D1154A137843F0020313700AE0084B1A795AB998781B791749DBB2CA5C22EA0002CA54BDE83840FFF7D9BA002038BD00BF00600040AC | ||||
| :402200006086FF1F6C86FF1F942F0000F82F0000802F00006B300000EA86FF1F7886FF1F5186FF1F6F86FF1F7186FF1F5E86FF1F5C86FF1F7086FF1F6D86FF1FE686FF1FDE | ||||
| :402240007386FF1F074B1A78120609D55B78012B06D1054B054A5A6012781A80FFF7C4BB00207047006000406086FF1F582F0000024B1878C0F38010704700BF8F450040F9 | ||||
| :40228000704738B505460078012428B100F0D0F8285D0134E4B2F8E738BD08B50D2000F0C7F8BDE808400A2000F0C2B8014B1870704700BF7D640040014B1878704700BF06 | ||||
| :4022C0006B640040014B1870704700BF78650040074A0223136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E073B515461E460B4C40 | ||||
| :40228000704738B505460078012428B100F0D0F8285D0134E4B2F8E738BD08B50D2000F0C7F8BDE808400A2000F0C2B8014B1870704700BF7C640040014B1878704700BF07 | ||||
| :4022C0006A640040014B1870704700BF78650040074A0223136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E073B515461E460B4C41 | ||||
| :402300000023019300930A46014618462370FEF747FE324629462078FEF702FE02212078FEF7ECFD207802B070BD00BFF480FF1F064A0123136002F688321268E021106434 | ||||
| :40234000034A1170A2F540721360704780E100E000E400E0014B1870704700BF7B640040014B1870704700BF79650040014B1870704700BF7A640040014B1870704700BF94 | ||||
| :402380007C640040014B1870704700BF7E64004073B515461E460B4C01230022019200920A46014618462370FEF7FAFD324629462078FEF7B5FD02212078FEF79FFD20786A | ||||
| :40234000034A1170A2F540721360704780E100E000E400E0014B1870704700BF79650040014B1870704700BF7A640040014B1870704700BF7B640040014B1870704700BF94 | ||||
| :402380007F640040014B1870704700BF7E64004073B515461E460B4C01230022019200920A46014618462370FEF7FAFD324629462078FEF7B5FD02212078FEF79FFD207867 | ||||
| :4023C00002B070BDF580FF1F064A0423136002F688321268E0219064034A1170A2F202321360704780E100E002E400E0014B04221A60704700E100E0014B04221A60704792 | ||||
| :4024000080E100E0014B1870704700BF7F6400400230800803D000BF01380046FCD17047EFF3108072B6704780F31088704700BFFEB5494652465B460EB407462449096865 | ||||
| :4024000080E100E0014B1870704700BF7D6400400230800803D000BF01380046FCD17047EFF3108072B6704780F31088704700BFFEB5494652465B460EB407462449096867 | ||||
| :402440008A46244A12682448022100F05FF8030020480068C018204900F058F8143883460121C9430C4601250026FFF7D9FF814651460B7823400B7058460130FFF7C8FF80 | ||||
| :402480003800F04028400B78234003430B705846FFF7BEFF0136072EF2D9002001300138013001200B78234003430B7058460430FFF7AEFF4846FFF7B7FF00BF00BF00BFAE | ||||
| :4024C0000EBC894692469B46FEBD00BFAFF30080E880FF1FE480FF1F00C20100094A137803F00303012B0AD0022B09D113790C2103F07F02044B01FB02339B7A00E0137911 | ||||
| @@ -186,7 +186,7 @@ | ||||
| :402E4000327800686F6D696E6700626567696E6E696E67207365656B2066726F6D20256420746F20256400756E65787065637465646C7920646574656374656420747261A1 | ||||
| :402E8000636B20300066696E6973686564207365656B0057616974696E6720666F72205553422E2E2E0055534220726561647900636F6D6D616E64203078253032780077D8 | ||||
| :402EC00061697400756E64657272756E206166746572202564207061636B65747300636F756E743D256420693D256420643D2564207A7A3D25640073746172742065726153 | ||||
| :402F000073696E670073746F702065726173696E670069646C650000510040100030510040400000000140000C800C0140800300140140000800400140000A004C014000BF | ||||
| :402F000073696E670073746F702065726173696E670069646C650000510040100030510040400000000140800A000B0140000500140140000800400140000A004C01400040 | ||||
| :402F400002005001402000303132333435363738394142434445460028000000000104000100000000000000000157494E5553420000303030303100000000000000000004 | ||||
| :402F800012034D0053004600540031003000300001000000010000009C2F0000010000006B300000000000000000000001000000B42F0000010000003D3000000400000072 | ||||
| :402FC000D62F0000000000000000000000000000D42F0000FF00000001024000FF00000082024000FF00000003034000FF00000084034000FF000203040309041603460042 | ||||
| @@ -4098,32 +4098,32 @@ | ||||
| :40FF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041 | ||||
| :40FFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 | ||||
| :0200000480007A | ||||
| :4000000001450040075200400564004002030140030501400107014006090140500A01404B0B0140270C0140510D01404B0E0140330F01400115014003170140161801404D | ||||
| :4000400025190140041B0140094001400A4101400E42014005430140044401401645014006460140094701400848014005490140164C0140034D01400550014003510140AF | ||||
| :400080007E020806094410861115600B610E7C402C802D0A3A803C7E7E01E202EE02E201E621EC02EE02964099209D40A140A220EE020201050107060D040E010F01130742 | ||||
| :4000C0001501170219071C0228042F07300132043307340238023B083E1540654104430145044602475E483549FF4AFF4BFF4D204EF051105608580459045A045B045C9002 | ||||
| :400100005D995F0161086280630C64406540664067A8684069A86B086D08800281018205860F880F8A208C0F8E1096409C029E34A001A20AA480AC40AF01B007B101B2C048 | ||||
| :40014000B638B902BA02BF01D804D904DB04DC09DF010002014005010604072209800E22100816501740188019201A201D011E221F09210C25012B022D40311032053908BC | ||||
| :400180003A403C024201430249144B485080520A582059405E406180630468096D807C207E08804081018B049140920B9340948095089620970A99109A549B629D05A2205A | ||||
| :4001C000A302A480A508A602A708AA10AC80B380C0F9C2A1C4B2CA18CC07CE8AD009D20CD61CD80CE620EC04810188058A0A8C02900B96049A029C029E0DA002B008B40797 | ||||
| :40020000B601B701BE41BF40C041C720C820C9FFCAFFCBFFCD20CEF0D110D608D804D904DA04DB04DC09DD99DF01E108E240E340E480E640E74001200202050106010720D3 | ||||
| :4002400009080A820B080D200EA00F0110801711184019301A011D201F60200125C02648272A2F213608371138023D803E103F2040414560460447084E0850015601571050 | ||||
| :4002800058A05E105F8062706680670569406F01831087048B408C01928A934094809508970898209B509D149ED09F20A210A302A480A5A8A622A708AA40B020B440C0B326 | ||||
| :4002C000C2FFC458CA50CCE0CE11D079D220D63CD83CE004E804EE020080010402400410050808400A800B200C280D080F011007113112F8130A1420150418021C181D04E1 | ||||
| :400300001EC1200628F829092A072B162D072E042F38303F313F34C03A203B03580459045B045C995D905F01808086408840890D8C018D708E329140940195019606980FB5 | ||||
| :4003400099A09A209C0F9E10A004A209A705AA0FAB50AD0AB1C0B207B30CB4C0B503B638B730BA08D804D90BDB04DC99DF01016002D0040405400680070809080A820B0866 | ||||
| :400380000DA00E2010841203172119201A881B021C041D401E201F20220123402440251026082759280429102B022E802F283080310432013628370139483A113C403D20D8 | ||||
| :4003C00069406E407E80C0FFC2EFC45BCA7CCCEBCE3FDE80EA04E280EA02EE040D021901330237013F4459045B045F01850191029C01B001B102B501BE01BF11D608D80435 | ||||
| :40040000D904DB04DD90DF0109801A4022012308268027103002362038083D8058205A805C405D206008618068026C046F0285408A818C488F10964099209D40A140A220CF | ||||
| :40044000C201CC21CE12D63CD80CE280E608EA02EE04AB02B420B640B70817043304340236803B443D80C420CCE0CE703380372085409744A540A680AC02CC30E240EE409B | ||||
| :4004800050085710800883108B0497449F20A6C0A780AE40D460E280E680EC409F20A6C0A780AF40EE4014407380C404DC01500A56405D8062086640670280028A088F2038 | ||||
| :4004C00097209980A980AF10B040B780D407D605D802E002E401EA01EC089720A320A408AB01B008EE040B220E800F049720A320A408A640AE40C20F26408A80A6C0AB80D1 | ||||
| :40050000AF20C820EA40EE2077109B10AB10DE20EA20041008080C080F02508057205E80620187018A408E01A320A408AB01AF04C001C20DD406D604D802E004E402B49823 | ||||
| :40054000EA0AEC0201010D010F0111011D0100BD012A10050200000019006200000000001017002803400C02104828150300740480000000000001000063001C10004000CF | ||||
| :40058000000000010000000F7F3080702008000000004010260103000000E04028FFFFFF0020F00120100100000018000404040499990001000800004020800840200008B0 | ||||
| :4005C000000040A8000000000000000000000000000000003F00003F1F001F000000000000000000100000004000000000000000C0000000FF0020FF47004700000100009A | ||||
| :40060000A00000BFBF009F000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FC | ||||
| :40064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A | ||||
| :40000000014500400752004005640040010101400303014001050140010701400D090140100A0140460B01405C0C0140490D0140590E0140360F014001150140031701407A | ||||
| :400040002418014035190140061B01400C4001400D4101400742014005430140054401401445014008460140094701400948014008490140174C0140044D014005500140AF | ||||
| :40008000035101407E020803094610831196601561047C402B802D0A3B7E3E807E01E208E224E602EE02E020EA0188849140980199809C809D209E409F20A140A280A4408A | ||||
| :4000C000AF10EA09050408030E01110120022D0231043302360337013F45580B59045B045C095F0100800120058507040E601240171819801C201D2D1F0A21052301251099 | ||||
| :40010000260C27182A402F2A3002361838083D223E403F04452A4E88560858805F506409668068026C046D40780179407B01830185058B408C489240930494409B049C01D3 | ||||
| :400140009D859E889F28A143A210A320A410A604A701AD80C0F3C230C468CA78CC61CEF2D0E0D220D638D830DE01E029E402E808001002400403060C080209010B021201CF | ||||
| :4001800014031674170118191A621B061E80228024102628281029012B042F01307F327F34803507382A3E10580459045B045C995F018018820184078502863889488A047E | ||||
| :4001C0008B908D088F349028945095FD97029B029C209D02A006A102A3FDA402A503A7F8A838AA07AC80ADA0AF48B040B23FB307B401B5C0B680B738BBA0BE51C021C720DA | ||||
| :40020000C820C9FFCAFFCBFFCD20CEF0D110D804D904DA04DB04DC99DD09DF01E108E240E340E480E640E740010A02040515080809800A800E680F0210A212081608170980 | ||||
| :40024000180519081B0A1D021E201F1421D0220826202704290A2A802D802F0430A03208362439A03A043C20400550025C405F2068016D806F018302870288018B108C0233 | ||||
| :4002800092C09304980899129A049C019D0C9E80A0A0A101A320A410A580A61CA708AC02B0A0B310C07EC2FDC47FCA3BCC6ECE2ED00CD630E008E220E6020447050A063891 | ||||
| :4002C00008040C310E4A0F0510081201150D162019011C082004240428492A16303F33033440350C3A033E10406441034302452446E04705481B49FF4AFF4BFF4D204EF0B5 | ||||
| :40030000511056085804590B5A045B045C995D995F0161086280630C64406540664067A8684069A86B086D088001820A8306840F86108701880289018A058B02900292340E | ||||
| :40034000940F9620970199019A0F9B049E40A480A840B038B107B407B6C0BA20D201D610D804D904DB04DC99DD90DF0100400108020405140680080809800A800D020E2AAA | ||||
| :4003800010A0120816101720184019021A041D121E021F602128232425013128361438043B803C203D023F0440404204430848A04A085204531058A0600E62106A806E4015 | ||||
| :4003C0007801C077C2FDC46ECC66CEEAD007D204D60CD80CDE01E208EA01E201E680EA0205010F022D023301350239203F14560859045B045D905F01800288018C018F0427 | ||||
| :400400009D01A502A804A904AD08AE01B004B10CB301B403B502BE01BF14D608D80BD904DB04DC99DD90DF0101A00240100812021880192020C821082202272429202A4043 | ||||
| :400440002B102D4032403680378038403D803F0859145A405F806240632867016A806C086F02780183018B028D108E409140980199809D209E409F20A140A280A444C00BA7 | ||||
| :40048000C403CA1ECC08CE58D61ED81EDE01E680EA02A904AB04AD08B440E802EE01170433043402371039043A203E808620C420CCE0CE70E21030203720831084028A08BE | ||||
| :4004C0009C029E809F10AD04CC30E220E640EE40560889809A089E809F20A420D4409E809F20A580A820EA8014407E018710C404DE045104564058405D8062086740858012 | ||||
| :40050000871088408A018E4096029710B040D407D604D803E005E402EA01820286088740924095089770A608AE400B210F149240950897B1A202AB01AF40C20F25808280E6 | ||||
| :400540008B029E80A580AF20C820E280EA4073807F029B80A302AB80DC80DE20EA8005200B800C020D040F08520254205E4061028C028F04924095089780A202AF04C001D7 | ||||
| :40058000C20DD403D604D802E202E602A920AD02B420EC0801010D010F0111011D0100BD012A10050820324039804620082010C42000080280000000FE1001ED00E3001C2E | ||||
| :4005C00000000000000000000000040182EF3D10000000083800C11F07E0000000080220000010004603020000E0000412FFFFFF0020F00120100000000008000404040460 | ||||
| :4006000099990001000800004020800840200008000040A8000000000000000000000000000000003F0000201F001F0000000000000000001000000040000000000000005A | ||||
| :40064000C0000000FF0000B84700470000010000A000003FBF009F000000000000010000000000000000000000000000000000000000000000000000000000000000000036 | ||||
| :40068000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A | ||||
| :4006C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA | ||||
| :4007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9 | ||||
| @@ -4615,12 +4615,12 @@ | ||||
| :0200000490105A | ||||
| :04000000BC90ACAF55 | ||||
| :0200000490303A | ||||
| :0200000033F2D9 | ||||
| :020000004B149F | ||||
| :0200000490402A | ||||
| :4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0 | ||||
| :400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080 | ||||
| :400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040 | ||||
| :4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| :0200000490501A | ||||
| :0C00000000012E16106900002E2A445B3F | ||||
| :0C00000000012E16106900002E2A5B7D06 | ||||
| :00000001FF | ||||
| @@ -530,31 +530,38 @@ | ||||
| <CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3"> | ||||
| <CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED" persistent=""> | ||||
| <Hidden v="False" /> | ||||
| <Hidden v="True" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2"> | ||||
| <dependencies> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED_aliases.h" persistent="Generated_Source\PSoC5\LED_aliases.h"> | ||||
| <Hidden v="False" /> | ||||
| <Hidden v="True" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="HEADER;;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED.c" persistent="Generated_Source\PSoC5\LED.c"> | ||||
| <Hidden v="False" /> | ||||
| <Hidden v="True" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="SOURCE_C;CortexM3;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED.h" persistent="Generated_Source\PSoC5\LED.h"> | ||||
| <Hidden v="False" /> | ||||
| <Hidden v="True" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="HEADER;;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED_PM.c" persistent="Generated_Source\PSoC5\LED_PM.c"> | ||||
| <Hidden v="True" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="SOURCE_C;CortexM3;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| </dependencies> | ||||
| </CyGuid_0820c2e7-528d-4137-9a08-97257b946089> | ||||
| </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8> | ||||
| @@ -3282,6 +3289,39 @@ | ||||
| </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8> | ||||
| <filters /> | ||||
| </CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0> | ||||
| <CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3"> | ||||
| <CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED_PIN" persistent=""> | ||||
| <Hidden v="False" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2"> | ||||
| <dependencies> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED_PIN_aliases.h" persistent="Generated_Source\PSoC5\LED_PIN_aliases.h"> | ||||
| <Hidden v="False" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="HEADER;;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED_PIN.c" persistent="Generated_Source\PSoC5\LED_PIN.c"> | ||||
| <Hidden v="False" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="SOURCE_C;CortexM3;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| <CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1"> | ||||
| <CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="LED_PIN.h" persistent="Generated_Source\PSoC5\LED_PIN.h"> | ||||
| <Hidden v="False" /> | ||||
| </CyGuid_31768f72-0253-412b-af77-e7dba74d1330> | ||||
| <build_action v="HEADER;;;;" /> | ||||
| <PropertyDeltas /> | ||||
| </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b> | ||||
| </dependencies> | ||||
| </CyGuid_0820c2e7-528d-4137-9a08-97257b946089> | ||||
| </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8> | ||||
| <filters /> | ||||
| </CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0> | ||||
| </dependencies> | ||||
| </CyGuid_0820c2e7-528d-4137-9a08-97257b946089> | ||||
| </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8> | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| PACKAGES = zlib sqlite3 libusb-1.0 | ||||
|  | ||||
| export CFLAGS = -O3 -g --std=c++14 \ | ||||
| export CFLAGS = -Os -g --std=c++14 \ | ||||
| 	-ffunction-sections -fdata-sections | ||||
| export LDFLAGS = -O3 | ||||
| export LDFLAGS = -Os | ||||
|  | ||||
| ifeq ($(OS), Windows_NT) | ||||
| export CXX = /mingw32/bin/g++ | ||||
|   | ||||
| @@ -129,8 +129,8 @@ reverse engineered it to find out. | ||||
|  | ||||
| Standard Linux mtools will access the filesystem image and allow you to move | ||||
| files in and out. However, you'll need to change the media type bytes at | ||||
| offsets 0x015 and 0x100 from 0x58 to 0xf0 before mtools will touch it. Once | ||||
| done, this will work: | ||||
| offsets 0x015 and 0x100 from 0x58 to 0xf0 before mtools will touch it. The | ||||
| supplied `brother240tool` will do this. Once done, this will work: | ||||
|  | ||||
| ``` | ||||
| mdir -i brother.img | ||||
|   | ||||
| @@ -123,8 +123,12 @@ admittedly expensive.) | ||||
|     sheet](http://www.bitsavers.org/pdf/mitsubishi/floppy/M4851/TJ2-G30211A_M4851_DSHH_48TPI_OEM_Manual_Nov83.pdf): | ||||
|     the equivalent data sheet for a representative 5.25" drive. | ||||
|  | ||||
|   - [The DRG Business Machines YD-174 manual](https://electrickery.hosting.philpem.me.uk/comp/divcomp/doc/YE_Data_YD-174_8inchFloppyDriveTechnicalManual.pdf): | ||||
| 	the equivalent manual (data sheets hadn't been invented then) for a | ||||
| 	representative 8" drive. | ||||
|  | ||||
|   - [KryoFlux stream file | ||||
|     documentation](https://www.kryoflux.com/download/kryoflux_stream_protocol_rev1.1.pdf): | ||||
|     the format of KryoFlux stream files (partially supported by FluxEngine) | ||||
|  | ||||
|    | ||||
|    | ||||
|   | ||||
							
								
								
									
										29
									
								
								doc/using.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								doc/using.md
									
									
									
									
									
								
							| @@ -221,6 +221,20 @@ directory. | ||||
|   file format in a non-backwards-compatible way; this tool will upgrade flux | ||||
|   files to the new format. | ||||
|  | ||||
|   - `fluxengine convert`: converts flux files from various formats to various | ||||
|   other formats. You can use this to convert Catweasel flux files to | ||||
|   FluxEngine's native format, FluxEngine flux files to various other formats | ||||
|   useful for debugging (including VCD which can be loaded into | ||||
|   [sigrok](http://sigrok.org)), and bidirectional conversion to and from | ||||
|   Supercard Pro `.scp` format. | ||||
|  | ||||
|   **Important SCP note:** import (`fluxengine convert scptoflux`) should be | ||||
|   fairly robust, but export (`fluxengine convert fluxtoscp`) should only be | ||||
|   done with great caution as FluxEngine files contain features which can't be | ||||
|   represented very well in `.scp` format and they're probably pretty dubious. | ||||
|   As ever, please [get in | ||||
|   touch](https://github.com/davidgiven/fluxengine/issues/new) with any reports. | ||||
|  | ||||
| Commands which normally take `--source` or `--dest` get a sensible default if | ||||
| left unspecified. `fluxengine read ibm` on its own will read drive 0 and | ||||
| write an `ibm.img` file. | ||||
| @@ -247,25 +261,24 @@ wrote to do useful things. These are built alongside FluxEngine. | ||||
|  | ||||
|   - `brother120tool`: extracts files from a 120kB Brother filesystem image. | ||||
|  | ||||
|   - `cwftoflux`: converts (one flavour of) CatWeasel flux file into a | ||||
|     FluxEngine flux file. | ||||
|  | ||||
| ## The recommended workflow | ||||
|  | ||||
| So you've just received, say, a huge pile of old Brother word processor disks containing valuable historical data, and you want to read them. | ||||
| So you've just received, say, a huge pile of old Brother word processor disks | ||||
| containing valuable historical data, and you want to read them. | ||||
|  | ||||
| Typically I do this: | ||||
|  | ||||
| ``` | ||||
| $ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux | ||||
| $ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux --write-svg=brother.svg | ||||
| ``` | ||||
|  | ||||
| This will read the disk in drive 0 and write out a filesystem image. It'll | ||||
| also copy the flux to brother.flux. If I then need to tweak the settings, I | ||||
| can rerun the decode without having to physically touch the disk like this: | ||||
| also copy the flux to brother.flux and write out an SVG visualisation. If I | ||||
| then need to tweak the settings, I can rerun the decode without having to | ||||
| physically touch the disk like this: | ||||
|  | ||||
| ``` | ||||
| $ fluxengine read brother -s brother.flux -o brother.img | ||||
| $ fluxengine read brother -s brother.flux -o brother.img --write-svg=brother.svg | ||||
| ``` | ||||
|  | ||||
| Apart from being drastically faster, this avoids touching the (potentially | ||||
|   | ||||
							
								
								
									
										88
									
								
								lib/flags.cc
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								lib/flags.cc
									
									
									
									
									
								
							| @@ -29,7 +29,7 @@ void FlagGroup::addFlag(Flag* flag) | ||||
|     _flags.push_back(flag); | ||||
| } | ||||
|  | ||||
| void FlagGroup::parseFlags(int argc, const char* argv[]) | ||||
| std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc, const char* argv[]) | ||||
| { | ||||
|     if (_initialised) | ||||
|         throw std::runtime_error("called parseFlags() twice"); | ||||
| @@ -66,6 +66,7 @@ void FlagGroup::parseFlags(int argc, const char* argv[]) | ||||
|  | ||||
|     /* Now actually parse them. */ | ||||
|  | ||||
|     std::vector<std::string> filenames; | ||||
|     int index = 1; | ||||
|     while (index < argc) | ||||
|     { | ||||
| @@ -76,52 +77,73 @@ void FlagGroup::parseFlags(int argc, const char* argv[]) | ||||
|         std::string value; | ||||
|         bool usesthat = false; | ||||
|  | ||||
|         if ((thisarg.size() == 0) || (thisarg[0] != '-')) | ||||
|             Error() << "non-option parameter " << thisarg << " seen (try --help)"; | ||||
|         if ((thisarg.size() > 1) && (thisarg[1] == '-')) | ||||
|         if (thisarg.size() == 0) | ||||
|         { | ||||
|             /* Long option. */ | ||||
|  | ||||
|             auto equals = thisarg.rfind('='); | ||||
|             if (equals != std::string::npos) | ||||
|             { | ||||
|                 key = thisarg.substr(0, equals); | ||||
|                 value = thisarg.substr(equals+1); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 key = thisarg; | ||||
|                 value = thatarg; | ||||
|                 usesthat = true; | ||||
|             } | ||||
|             /* Ignore this argument. */ | ||||
|         } | ||||
|         else if (thisarg[0] != '-') | ||||
|         { | ||||
|             /* This is a filename. */ | ||||
|             filenames.push_back(thisarg); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             /* Short option. */ | ||||
|             /* This is a flag. */ | ||||
|  | ||||
|             if (thisarg.size() > 2) | ||||
|             if ((thisarg.size() > 1) && (thisarg[1] == '-')) | ||||
|             { | ||||
|                 key = thisarg.substr(0, 2); | ||||
|                 value = thisarg.substr(2); | ||||
|                 /* Long option. */ | ||||
|  | ||||
|                 auto equals = thisarg.rfind('='); | ||||
|                 if (equals != std::string::npos) | ||||
|                 { | ||||
|                     key = thisarg.substr(0, equals); | ||||
|                     value = thisarg.substr(equals+1); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     key = thisarg; | ||||
|                     value = thatarg; | ||||
|                     usesthat = true; | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 key = thisarg; | ||||
|                 value = thatarg; | ||||
|                 usesthat = true; | ||||
|                 /* Short option. */ | ||||
|  | ||||
|                 if (thisarg.size() > 2) | ||||
|                 { | ||||
|                     key = thisarg.substr(0, 2); | ||||
|                     value = thisarg.substr(2); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     key = thisarg; | ||||
|                     value = thatarg; | ||||
|                     usesthat = true; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             auto flag = flags_by_name.find(key); | ||||
|             if (flag == flags_by_name.end()) | ||||
|                 Error() << "unknown flag '" << key << "'; try --help"; | ||||
|  | ||||
|             flag->second->set(value); | ||||
|             if (usesthat && flag->second->hasArgument()) | ||||
|                 index++; | ||||
|         } | ||||
|  | ||||
|         auto flag = flags_by_name.find(key); | ||||
|         if (flag == flags_by_name.end()) | ||||
|             Error() << "unknown flag '" << key << "'; try --help"; | ||||
|  | ||||
|         flag->second->set(value); | ||||
|  | ||||
|         index++; | ||||
|         if (usesthat && flag->second->hasArgument()) | ||||
|             index++; | ||||
|     } | ||||
|  | ||||
|     return filenames; | ||||
| } | ||||
|  | ||||
| void FlagGroup::parseFlags(int argc, const char* argv[]) | ||||
| { | ||||
|     auto filenames = parseFlagsWithFilenames(argc, argv); | ||||
|     if (!filenames.empty()) | ||||
|         Error() << "non-option parameter " << *filenames.begin() << " seen (try --help)"; | ||||
| } | ||||
|  | ||||
| void FlagGroup::checkInitialised() const | ||||
|   | ||||
| @@ -14,6 +14,7 @@ public: | ||||
|  | ||||
| public: | ||||
|     void parseFlags(int argc, const char* argv[]); | ||||
|     std::vector<std::string> parseFlagsWithFilenames(int argc, const char* argv[]); | ||||
|     void addFlag(Flag* flag); | ||||
|     void checkInitialised() const; | ||||
|  | ||||
|   | ||||
| @@ -190,6 +190,7 @@ buildlibrary libfrontend.a \ | ||||
|     src/fe-cwftoflux.cc \ | ||||
|     src/fe-erase.cc \ | ||||
|     src/fe-fluxtoau.cc \ | ||||
|     src/fe-fluxtoscp.cc \ | ||||
|     src/fe-fluxtovcd.cc \ | ||||
|     src/fe-inspect.cc \ | ||||
|     src/fe-readadfs.cc \ | ||||
| @@ -208,6 +209,7 @@ buildlibrary libfrontend.a \ | ||||
|     src/fe-readvictor9k.cc \ | ||||
|     src/fe-readzilogmcz.cc \ | ||||
|     src/fe-rpm.cc \ | ||||
|     src/fe-scptoflux.cc \ | ||||
|     src/fe-seek.cc \ | ||||
|     src/fe-testbulktransport.cc \ | ||||
|     src/fe-upgradefluxfile.cc \ | ||||
| @@ -231,6 +233,13 @@ buildsimpleprogram brother120tool \ | ||||
|     libemu.a \ | ||||
|     libfmt.a \ | ||||
|  | ||||
| buildsimpleprogram brother240tool \ | ||||
| 	-Idep/emu \ | ||||
|     tools/brother240tool.cc \ | ||||
|     libbackend.a \ | ||||
|     libemu.a \ | ||||
|     libfmt.a \ | ||||
|  | ||||
| runtest bitaccumulator-test tests/bitaccumulator.cc | ||||
| runtest bytes-test          tests/bytes.cc | ||||
| runtest compression-test    tests/compression.cc | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| #include "fluxmap.h" | ||||
| #include "writer.h" | ||||
|  | ||||
| static FlagGroup flags; | ||||
| static FlagGroup flags { &writerFlags }; | ||||
|  | ||||
| int mainErase(int argc, const char* argv[]) | ||||
| { | ||||
|   | ||||
							
								
								
									
										188
									
								
								src/fe-fluxtoscp.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								src/fe-fluxtoscp.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| #include "globals.h" | ||||
| #include "flags.h" | ||||
| #include "fluxmap.h" | ||||
| #include "sql.h" | ||||
| #include "bytes.h" | ||||
| #include "protocol.h" | ||||
| #include "dataspec.h" | ||||
| #include "fmt/format.h" | ||||
| #include "decoders/fluxmapreader.h" | ||||
| #include "scp.h" | ||||
| #include <fstream> | ||||
| #include <algorithm> | ||||
|  | ||||
| static FlagGroup flags { }; | ||||
|  | ||||
| static SettableFlag fortyTrackMode( | ||||
|     { "--48", "-4" }, | ||||
|     "set 48 tpi mode; only every other physical track is emitted" | ||||
| ); | ||||
|  | ||||
| static SettableFlag singleSided( | ||||
|     { "--single-sided", "-s" }, | ||||
|     "only emit side 0" | ||||
| ); | ||||
|  | ||||
| static IntFlag diskType( | ||||
|     { "--disk-type" }, | ||||
|     "sets the SCP disk type byte", | ||||
|     0xff | ||||
| ); | ||||
|  | ||||
| static sqlite3* inputDb; | ||||
|  | ||||
| static void syntax() | ||||
| { | ||||
|     std::cout << "Syntax: fluxengine convert fluxtoscp <fluxfile> <scpfile>\n"; | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| static void write_le32(uint8_t dest[4], uint32_t v) | ||||
| { | ||||
|     dest[0] = v; | ||||
|     dest[1] = v >> 8; | ||||
|     dest[2] = v >> 16; | ||||
|     dest[3] = v >> 24; | ||||
| } | ||||
|  | ||||
| static int strackno(int track, int side) | ||||
| { | ||||
|     if (fortyTrackMode) | ||||
|         track /= 2; | ||||
|     if (singleSided) | ||||
|         return track; | ||||
|     else | ||||
|         return (track << 1) | side; | ||||
| } | ||||
|  | ||||
| int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
| { | ||||
|     auto filenames = flags.parseFlagsWithFilenames(argc, argv); | ||||
|     if (filenames.size() != 2) | ||||
|         syntax(); | ||||
|  | ||||
|     inputDb = sqlOpen(filenames[0], SQLITE_OPEN_READONLY); | ||||
|     auto tracks = sqlFindFlux(inputDb); | ||||
|  | ||||
|     int maxTrack = 0; | ||||
|     int maxSide = 0; | ||||
|     for (auto p : tracks) | ||||
|     { | ||||
|         if (singleSided && (p.second == 1)) | ||||
|             continue; | ||||
|         maxTrack = std::max(maxTrack, (int)p.first); | ||||
|         maxSide = std::max(maxSide, (int)p.second); | ||||
|     } | ||||
|     int maxStrack = strackno(maxTrack, maxSide); | ||||
|  | ||||
|     std::cout << fmt::format("Writing {} {} SCP file containing {} SCP tracks\n", | ||||
|         fortyTrackMode ? "48 tpi" : "96 tpi", | ||||
|         singleSided ? "single sided" : "double sided", | ||||
|         maxStrack + 1 | ||||
|     ); | ||||
|  | ||||
|     ScpHeader fileheader = {0}; | ||||
|     fileheader.file_id[0] = 'S'; | ||||
|     fileheader.file_id[1] = 'C'; | ||||
|     fileheader.file_id[2] = 'P'; | ||||
|     fileheader.file_id[3] = 0x18; /* Version 1.8 of the spec */ | ||||
|     fileheader.type = diskType; | ||||
|     fileheader.revolutions = 5; | ||||
|     fileheader.start_track = 0; | ||||
|     fileheader.end_track = maxStrack; | ||||
|     fileheader.flags = SCP_FLAG_INDEXED | (fortyTrackMode ? 0 : SCP_FLAG_96TPI); | ||||
|     fileheader.cell_width = 0; | ||||
|     fileheader.heads = singleSided ? 1 : 0; | ||||
|  | ||||
|     Bytes trackdata; | ||||
|     ByteWriter trackdataWriter(trackdata); | ||||
|  | ||||
|     int trackstep = 1 + fortyTrackMode; | ||||
|     int maxside = singleSided ? 0 : 1; | ||||
|     for (int track = 0; track <= maxTrack; track += trackstep) | ||||
|     { | ||||
|         for (int side = 0; side <= maxside; side++) | ||||
|         { | ||||
|             int strack = strackno(track, side); | ||||
|             std::cout << fmt::format("FE track {}.{}, SCP track {}: ", track, side, strack) << std::flush; | ||||
|  | ||||
|             auto fluxmap = sqlReadFlux(inputDb, track, side); | ||||
|             ScpTrack trackheader = {0}; | ||||
|             trackheader.track_id[0] = 'T'; | ||||
|             trackheader.track_id[1] = 'R'; | ||||
|             trackheader.track_id[2] = 'K'; | ||||
|             trackheader.strack = strack; | ||||
|  | ||||
|             FluxmapReader fmr(*fluxmap); | ||||
|             Bytes fluxdata; | ||||
|             ByteWriter fluxdataWriter(fluxdata); | ||||
|  | ||||
|             int revolution = 0; | ||||
|             unsigned revTicks = 0; | ||||
|             unsigned totalTicks = 0; | ||||
|             unsigned ticksSinceLastPulse = 0; | ||||
|             uint32_t startOffset = 0; | ||||
|             while (revolution < 5) | ||||
|             { | ||||
|                 unsigned ticks; | ||||
|                 int opcode = fmr.readOpcode(ticks); | ||||
|                 if (ticks) | ||||
|                 { | ||||
|                     ticksSinceLastPulse += ticks; | ||||
|                     totalTicks += ticks; | ||||
|                     revTicks += ticks; | ||||
|                 } | ||||
|  | ||||
|                 switch (opcode) | ||||
|                 { | ||||
|                     case -1: /* end of flux, treat like an index marker */ | ||||
|                     case F_OP_INDEX: | ||||
|                     { | ||||
|                         auto* revheader = &trackheader.revolution[revolution]; | ||||
|                         write_le32(revheader->offset, startOffset + sizeof(ScpTrack)); | ||||
|                         write_le32(revheader->length, (fluxdataWriter.pos - startOffset) / 2); | ||||
|                         write_le32(revheader->index, revTicks * NS_PER_TICK / 25); | ||||
|                         revolution++; | ||||
|                         revheader++; | ||||
|                         revTicks = 0; | ||||
|                         startOffset = fluxdataWriter.pos; | ||||
|                         break; | ||||
|                     } | ||||
|  | ||||
|                     case F_OP_PULSE: | ||||
|                     { | ||||
|                         unsigned t = ticksSinceLastPulse * NS_PER_TICK / 25; | ||||
|                         while (t >= 0x10000) | ||||
|                         { | ||||
|                             fluxdataWriter.write_be16(0); | ||||
|                             t -= 0x10000; | ||||
|                         } | ||||
|                         fluxdataWriter.write_be16(t); | ||||
|                         ticksSinceLastPulse = 0; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             write_le32(fileheader.track[strack], trackdataWriter.pos + sizeof(ScpHeader)); | ||||
|             trackdataWriter += Bytes((uint8_t*)&trackheader, sizeof(trackheader)); | ||||
|             trackdataWriter += fluxdata; | ||||
|  | ||||
|             std::cout << fmt::format("{} ms in {} bytes\n", | ||||
|                 totalTicks * MS_PER_TICK, | ||||
|                 fluxdata.size()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     sqlClose(inputDb); | ||||
|      | ||||
|     std::cout << "Writing output file...\n"; | ||||
|     std::ofstream of(filenames[1], std::ios::out | std::ios::binary); | ||||
|     if (!of.is_open()) | ||||
|         Error() << "cannot open output file"; | ||||
|     of.write((const char*) &fileheader, sizeof(fileheader)); | ||||
|     of.write((const char*) trackdata.begin(), trackdata.size()); | ||||
|     of.close(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
| @@ -8,7 +8,7 @@ static FlagGroup flags; | ||||
| static DataSpecFlag source( | ||||
|     { "--source", "-s" }, | ||||
|     "source for data", | ||||
|     ":d=0"); | ||||
|     ":d=0:t=0:s=0"); | ||||
|  | ||||
| int mainRpm(int argc, const char* argv[]) | ||||
| { | ||||
|   | ||||
							
								
								
									
										142
									
								
								src/fe-scptoflux.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/fe-scptoflux.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| #include "globals.h" | ||||
| #include "fluxmap.h" | ||||
| #include "sql.h" | ||||
| #include "bytes.h" | ||||
| #include "protocol.h" | ||||
| #include "fmt/format.h" | ||||
| #include "scp.h" | ||||
| #include <fstream> | ||||
|  | ||||
| static std::ifstream inputFile; | ||||
| static sqlite3* outputDb; | ||||
| static ScpHeader header; | ||||
| static nanoseconds_t resolution; | ||||
| static int startSide; | ||||
| static int endSide; | ||||
|  | ||||
| static void syntax() | ||||
| { | ||||
|     std::cout << "Syntax: fluxengine convert cwftoflux <cwffile> <fluxfile>\n"; | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| static void check_for_error() | ||||
| { | ||||
|     if (inputFile.fail()) | ||||
|         Error() << fmt::format("I/O error: {}", strerror(errno)); | ||||
| } | ||||
|  | ||||
| static int trackno(int strack) | ||||
| { | ||||
|     if (startSide == endSide) | ||||
|         return strack; | ||||
|     return strack >> 1; | ||||
| } | ||||
|  | ||||
| static int headno(int strack) | ||||
| { | ||||
|     if (startSide == endSide) | ||||
|         return startSide; | ||||
|     return strack & 1; | ||||
| } | ||||
|  | ||||
| static void read_header() | ||||
| { | ||||
|     inputFile.read((char*) &header, sizeof(header)); | ||||
|     check_for_error(); | ||||
|  | ||||
|     if ((header.file_id[0] != 'S') | ||||
|             || (header.file_id[1] != 'C') | ||||
|             || (header.file_id[2] != 'P')) | ||||
|         Error() << "input not a SCP file"; | ||||
|  | ||||
|     resolution = 25 * (header.resolution + 1); | ||||
|     startSide = (header.heads == 2) ? 1 : 0; | ||||
|     endSide = (header.heads == 1) ? 0 : 1; | ||||
|  | ||||
|     if ((header.cell_width != 0) && (header.cell_width != 16)) | ||||
|         Error() << "currently only 16-bit cells are supported"; | ||||
|  | ||||
|     std::cout << fmt::format("tracks {}-{}, heads {}-{}\n", | ||||
|         trackno(header.start_track), trackno(header.end_track), startSide, endSide); | ||||
|     std::cout << fmt::format("sample resolution: {} ns\n", resolution); | ||||
| } | ||||
|  | ||||
| static void read_track(int strack) | ||||
| { | ||||
|     uint32_t offset = Bytes(header.track[strack], 4).reader().read_le32(); | ||||
|  | ||||
|     ScpTrack trackheader; | ||||
|     inputFile.seekg(offset, std::ios::beg); | ||||
|     inputFile.read((char*) &trackheader, sizeof(trackheader)); | ||||
|     check_for_error(); | ||||
|  | ||||
|     if ((trackheader.track_id[0] != 'T') | ||||
|             || (trackheader.track_id[1] != 'R') | ||||
|             || (trackheader.track_id[2] != 'K')) | ||||
|         Error() << "corrupt SCP file"; | ||||
|  | ||||
|     std::cout << fmt::format("{}.{}: ", trackno(strack), headno(strack)) | ||||
|         << std::flush; | ||||
|  | ||||
|     Fluxmap fluxmap; | ||||
|     nanoseconds_t pending = 0; | ||||
|     unsigned inputBytes = 0; | ||||
|     for (int revolution = 0; revolution < header.revolutions; revolution++) | ||||
|     { | ||||
|         if (revolution != 0) | ||||
|             fluxmap.appendIndex(); | ||||
|  | ||||
|         uint32_t datalength = Bytes(trackheader.revolution[revolution].length, 4).reader().read_le32(); | ||||
|         uint32_t dataoffset = Bytes(trackheader.revolution[revolution].offset, 4).reader().read_le32(); | ||||
|  | ||||
|         Bytes data(datalength*2); | ||||
|         inputFile.seekg(dataoffset + offset, std::ios::beg); | ||||
|         inputFile.read((char*) data.begin(), data.size()); | ||||
|         check_for_error(); | ||||
|  | ||||
|         ByteReader br(data); | ||||
|         for (int cell = 0; cell < datalength; cell++) | ||||
|         { | ||||
|             uint16_t interval = br.read_be16(); | ||||
|             if (interval) | ||||
|             { | ||||
|                 fluxmap.appendInterval((interval + pending) * resolution / NS_PER_TICK); | ||||
|                 fluxmap.appendPulse(); | ||||
|                 pending = 0; | ||||
|             } | ||||
|             else | ||||
|                 pending += 0x10000; | ||||
|         } | ||||
|  | ||||
|         inputBytes += datalength*2; | ||||
|     } | ||||
|  | ||||
|     std::cout << fmt::format(" {} ms in {} input bytes and {} output bytes\n", | ||||
|         fluxmap.duration() / 1e6, inputBytes, fluxmap.bytes()); | ||||
|     sqlWriteFlux(outputDb, trackno(strack), headno(strack), fluxmap); | ||||
| } | ||||
|  | ||||
| int mainConvertScpToFlux(int argc, const char* argv[]) | ||||
| { | ||||
|     if (argc != 3) | ||||
|         syntax(); | ||||
|      | ||||
|     inputFile.open(argv[1], std::ios::in | std::ios::binary); | ||||
|     if (!inputFile.is_open()) | ||||
| 		Error() << fmt::format("cannot open input file '{}'", argv[1]); | ||||
|  | ||||
|     outputDb = sqlOpen(argv[2], SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); | ||||
|     sqlPrepareFlux(outputDb); | ||||
|     sqlWriteIntProperty(outputDb, "version", FLUX_VERSION_CURRENT); | ||||
|     sqlStmt(outputDb, "BEGIN;"); | ||||
|  | ||||
|     read_header(); | ||||
|     inputFile.seekg(sizeof(header), std::ios::beg); | ||||
|     for (unsigned i=header.start_track; i<=header.end_track; i++) | ||||
|         read_track(i); | ||||
|  | ||||
|     sqlStmt(outputDb, "COMMIT;"); | ||||
|     sqlClose(outputDb); | ||||
|     return 0; | ||||
| } | ||||
| @@ -5,7 +5,9 @@ typedef int command_cb(int agrc, const char* argv[]); | ||||
| extern command_cb mainErase; | ||||
| extern command_cb mainConvertCwfToFlux; | ||||
| extern command_cb mainConvertFluxToAu; | ||||
| extern command_cb mainConvertFluxToScp; | ||||
| extern command_cb mainConvertFluxToVcd; | ||||
| extern command_cb mainConvertScpToFlux; | ||||
| extern command_cb mainInspect; | ||||
| extern command_cb mainReadADFS; | ||||
| extern command_cb mainReadAESLanier; | ||||
| @@ -83,7 +85,9 @@ static std::vector<Command> writeables = | ||||
| static std::vector<Command> convertables = | ||||
| { | ||||
|     { "cwftoflux",     mainConvertCwfToFlux, "Converts CatWeasel stream files to flux.", }, | ||||
|     { "scptoflux",     mainConvertScpToFlux, "Converts Supercard Pro stream files to flux.", }, | ||||
|     { "fluxtoau",      mainConvertFluxToAu,  "Converts (one track of a) flux file to an .au audio file.", }, | ||||
|     { "fluxtoscp",     mainConvertFluxToScp, "Converrt a flux file to a Supercard Pro file.", }, | ||||
|     { "fluxtovcd",     mainConvertFluxToVcd, "Converts (one track of a) flux file to a VCD file.", }, | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										43
									
								
								src/scp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/scp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| #ifndef SCP_H | ||||
| #define SCP_H | ||||
|  | ||||
| struct ScpHeader | ||||
| { | ||||
|     char file_id[3];       // file ID - 'SCP' | ||||
|     uint8_t version;       // major/minor in nibbles | ||||
|     uint8_t type;          // disk type - subclass/class in nibbles | ||||
|     uint8_t revolutions;   // up to 5 | ||||
|     uint8_t start_track;   // 0..165 | ||||
|     uint8_t end_track;     // 0..165 | ||||
|     uint8_t flags;         // see below | ||||
|     uint8_t cell_width;    // in bits, 0 meaning 16 | ||||
|     uint8_t heads;         // 0 = both, 1 = side 0 only, 2 = side 1 only | ||||
|     uint8_t resolution;    // 25ns * (resolution+1) | ||||
|     uint8_t checksum[4];   // of data after this point | ||||
|     uint8_t track[165][4]; // track offsets, not necessarily 165 | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|     SCP_FLAG_INDEXED    = (1<<0), | ||||
|     SCP_FLAG_96TPI      = (1<<1), | ||||
|     SCP_FLAG_360RPM     = (1<<2), | ||||
|     SCP_FLAG_NORMALIZED = (1<<3), | ||||
|     SCP_FLAG_READWRITE  = (1<<4), | ||||
|     SCP_FLAG_FOOTER     = (1<<5) | ||||
| }; | ||||
|  | ||||
| struct ScpTrack | ||||
| { | ||||
|     char track_id[3];      // 'TRK' | ||||
|     uint8_t strack;        // SCP track number | ||||
|     struct | ||||
|     { | ||||
|         uint8_t index[4];  // time for one revolution | ||||
|         uint8_t length[4]; // number of bitcells | ||||
|         uint8_t offset[4]; // offset to bitcell data, relative to track header | ||||
|     } | ||||
|     revolution[5]; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										56
									
								
								tools/brother240tool.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								tools/brother240tool.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| #include "globals.h" | ||||
| #include "fmt/format.h" | ||||
| #include <fstream> | ||||
|  | ||||
| static std::fstream inputFile; | ||||
|  | ||||
| void syntax() | ||||
| { | ||||
|     std::cout << "Syntax: brother240tool <image>\n" | ||||
|                  "The disk image will be flipped from Brother to DOS format and back\n" | ||||
|                  "again.\n"; | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| uint8_t getbyte(uint32_t offset) | ||||
| { | ||||
|     inputFile.seekg(offset, std::ifstream::beg); | ||||
|     return inputFile.get(); | ||||
| } | ||||
|  | ||||
| void putbyte(uint32_t offset, uint8_t value) | ||||
| { | ||||
|     inputFile.seekp(offset, std::ifstream::beg); | ||||
|     inputFile.put(value); | ||||
| } | ||||
|  | ||||
| int main(int argc, const char* argv[]) | ||||
| { | ||||
|     if (argc < 2) | ||||
|         syntax(); | ||||
|      | ||||
|     inputFile.open(argv[1], std::ios::in | std::ios::out | std::ios::binary); | ||||
|     if (!inputFile.is_open()) | ||||
| 		Error() << fmt::format("cannot open input file '{}'", argv[1]); | ||||
|  | ||||
|     uint8_t b1 = getbyte(0x015); | ||||
|     uint8_t b2 = getbyte(0x100); | ||||
|     if ((b1 == 0x58) && (b2 == 0x58)) | ||||
|     { | ||||
|         std::cerr << "Flipping from Brother to DOS.\n"; | ||||
|         putbyte(0x015, 0xf0); | ||||
|         putbyte(0x100, 0xf0); | ||||
|     } | ||||
|     else if ((b1 == 0xf0) && (b2 == 0xf0)) | ||||
|     { | ||||
|         std::cerr << "Flipping from DOS to Brother.\n"; | ||||
|         putbyte(0x015, 0x58); | ||||
|         putbyte(0x100, 0x58); | ||||
|     } | ||||
|     else | ||||
|         Error() << "Unknown image format."; | ||||
|  | ||||
|     inputFile.close(); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user