From 8755d108edadc9f627e9db6f18fde1d96f0e4b09 Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 11 Jul 2019 23:16:02 +0200 Subject: [PATCH 1/5] Sanity check Mac sectors --- reject anything with an out-of-bounds sector ID. --- lib/macintosh/decoder.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/macintosh/decoder.cc b/lib/macintosh/decoder.cc index fb90dad2..f7ec7568 100644 --- a/lib/macintosh/decoder.cc +++ b/lib/macintosh/decoder.cc @@ -153,6 +153,9 @@ void MacintoshDecoder::decodeSectorRecord() uint8_t formatByte = decode_data_gcr(header[3]); uint8_t wantedsum = decode_data_gcr(header[4]); + if (encodedSector > 11) + return; + _sector->logicalTrack = _track->physicalTrack; _sector->logicalSide = decode_side(encodedSide); _sector->logicalSector = encodedSector; From 56a36072f7491142b25fb03f5f3714059e718999 Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 12 Jul 2019 21:09:53 +0200 Subject: [PATCH 2/5] Sampler state machine cleanup; more debugging tools for the logic analyser. --- FluxEngine.cydsn/FluxEngine.cyprj | 37 ++++++++++++++++++- FluxEngine.cydsn/TopDesign/TopDesign.cysch | Bin 209136 -> 215882 bytes FluxEngine.cydsn/UdbSampler/UdbSampler.cyudb | Bin 146871 -> 148713 bytes FluxEngine.cydsn/main.c | 4 +- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/FluxEngine.cydsn/FluxEngine.cyprj b/FluxEngine.cydsn/FluxEngine.cyprj index 50510e35..4566365c 100644 --- a/FluxEngine.cydsn/FluxEngine.cyprj +++ b/FluxEngine.cydsn/FluxEngine.cyprj @@ -2310,13 +2310,13 @@ - + - + @@ -3249,6 +3249,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FluxEngine.cydsn/TopDesign/TopDesign.cysch b/FluxEngine.cydsn/TopDesign/TopDesign.cysch index c27d80c8eb6e9e74b096aa783f95c9988df53feb..ffe2bf131c9393ba1875f94bdaec18977de6b456 100644 GIT binary patch literal 215882 zcmeFa3!Gm?dH?_2NJK#@ip5J&*X$93keF;XH;PC$A%Kt&Nw_FV$X*g6xtT1NSgn!T zR#B|hR%^XgTU#%!t<}~`Ym2nns(5Xyz}c31sjd9AFaKz75%KqV&vWK`=A84roOAY@ zWCP#iwP(-HnR(`!=XvItXP$Xx=9Q-$(+K}PFyQ}s+P};_$REf2nCIMsqzBIfC)_u% zUP-GP`x|Q-lZ}0i?Tu}XU3%NwSg6$9jh*_xTPX`0qm3>4KIzi;H&!Xfc;i~-zd>o2 zyAqTp@6dE(;DJUI&lO}{X8jBi>1!P=r3mVJxHm1}C`nFVGR_bj`sY_kj zr1C6jY<15q`aPl4Nj;DMkK^Lm&px;6e5yLG`_+Ze8 zqwY#kbeVe_SIVT`R_gz9{WmdPCTg#cU~bjdF_jwDZzqTe?Vpm+4XRxzR6IJXgal~p z7qyN*{zm~9$Z6uTT~ML#L^IFH2{d})O=`>~s`EvHOAd*4D$EaeL^NRr6C-E^B8KAI zUYI=*e^ylpxb@~S_2fxMM#!>20t3#~SoURwF$;PuJQj>b0 za*%hp92@jEl-jNuF4EWi4Z7cTdfVmlQ+`L|h5DbcY+U4DB;t?gxlGj{qC3;6c(O*Vfo)xO{_#X|J0&bFht=Q5Vf+eUzhcQ)+(p%!>XH0Kfl?JL4 zLVksXNiVvj*HQ}`lT3P8qm6d5mR`aZJ8~`F?4=QrM zq-fYl(MHF6Bw?qxyV3D)yK-%F9Na0nKw0l~Tx>5LNQV9NLNdlgr{%(Psp?)Tsx21P zmWZnKN&4*zh1<;JABtq@JgfQvGLPAT$ZXO71x{!dC&GnhpGbsju@kNdmw&m4vsI;r zMYdrP4MRlzfMM)}`Y>breaL^a#v_Ng>KGfd-|cf(WRBFt*VGrB5oI9x*8t zSLg>WPwMM(*He}xJ)-h3FD$%y!6-Z4*dPuw*k^mth8Ze?H5u3&h53}%UL$G%L|85{ zUFLWN7q>`YA;7TGFe$gVhN31`=G?=g?=WxMLj&*m%rBU%gw$#Gx;=M0TiAcLwuo+H%DeB zExl@MBDTvUa#*U^om-q>B8C_c*8doEOl+6CH0DVdAD9&kOblpgXM<)k9y6Q3yj)2`)4A&-g_+q;a}Pe+y{lJJ<4kR+jbaNb zY^Q3+EFW(=0Vb^iL;;Hzo}m-Rl!X~8Rxwi`8iu2VW`ew_Av7n=g9J1cN+(W$;|%UI z^a~C$&)BC@%+AoU#>3r0#t>qj5GbT5eyR#a@t~f$xm6T1JVo)--6x3S9S!+97=-bA z1aOu6#9E53*YjbI+iX!0EeI`Itr3l9q9A-L1quOUTE!sCAk4_NKq7@}(+20o5*=pX zHXBFOY$#?P&e*otDT?KKnsUe*?5SvB7ubMG=SNj!1>i}uLI8?b&TdhdxdzH}B@qf{ z*o&Orz!!!9pi5AXyfGU`Q1FkNhlBhRO63Qm2lEI^&xGPsiCHUsvq?4V)tBuOhobTG zj9DTQc_p34dUlJ*)icx<#X&0H{zPQ(P?)K(Sc49>F;jbUsxt9s*uo+nmLM?~wvl?V zLw(?^m@R^u zb9dNOD2i{AFhucwJxw^gM`O3l)d`tE6S=kAfd`H`=Eo9C??z7@1TAciDE>tUe$au> zEEGiX&F<4Lxlb6ge!*u-;@f7xisDzfLW8bQ4&H0sr(4}8;CV5>v8c_W_}5+LL6V>Tl)_~+Wo-;qj1lIig(zOeT^6AD%81Ntm-RE& z+EB~M2t4N}VJN~Q1bptnW86~@TfIGy)H*Z%vJAz7W*Uicmnuj=V-nzpV4iD}cvfdI z6|h3_7BU}ZE^PB*)^%~BPv{HFAlR-r1H`tu2bsnTF8sn4HHQ#uT9fix+$2ASnH4@T z#0Mkzu4(}WNcq46r=4~uTn3!i4C&{5G=q0n?h%ptxEgRlF}X zp96iC_56AyJr-$>P0G0~XC*x#l*@1{>tbm&$^JnMs^LDP5PqD?%5)6pVy zOU-n}cw=+ko5(cXkAN7gAC@ARZev67HX>QX&%=r_UD0ePR*G3PVx5eVd~+@;LG&(U zf@4_kvH%PxIC;%agp>6G>&oV`X{p9cVGT`FWbmHT?$ob_8?)93L44e{^=f61<6Z$Svp_QU0 z@mR}5W7gcgV}qG1E<&aus7T&et=#I=B!NoshOim8{FYUMG-U2U3uMu2sszi5NcTp0 zW;|MTCCx!Nn0n)`wOA`=OWt)$V-Oss+<0+#!&%EHz!C~d5)JQ`Q?-gDv;}veexU*( z3&ATao>+XD~E4B{J_Tqd0mFH5Zb4@%wmS}-#u?kWkNw!?`0Ohu?LWb6nPND zhwN|MD8%-vvg~y4HbE*QMp;Gn;G72>y{b58^=Cr=uqW|JBZ6K=yb$^|1qRdoF4wAz zsHRa?Gw+$chNL&**%pQ52shnUCW6dS)j>X<@GrnLBTj!cFKJ#Oyq;- z6H1{&Vc+dF{P~Wnu`K?aV!Rtb3x#Oc{$a>-9$&b;4=0F$;7y=_og?&)L&!6~h@jN)Wm}aohwj$|*M1#UU z#!KWUZ;e|JB#x}DN&gC)&5Ug(QoByLP{VfBoyaJSf^9I7z+t42uu1Q=M{>=!q}eDh z*o&%S;fLl^&drxn>(RQMO#x35&ejE0<4j|yTCFzvjyI8ZJW$1yBTU^Ig+vYuO?XB; z6-~jLjJ(n)r7#0M}1qmy9& zvWkHWS@13{Zq_f*5GZ%7YYSsSPp~b-`G;Uqo^iCpW>v?%avM&|J_H(Gc<(J zoxS%m5oByOR;Lh5Mh&=bd^f#gel=!bM%FR?#-BDK@-pb-QA4hrOwiyw5g0zQM0iI) z1m2_got_AZ;(EBspt$J7Hr)D@8w)8|6xlp%?oi6mG*uV>4XzqU=k2Kd)0npph#p_l zAK8h<8W9W~XU67285(FUY$$Isv$)Wy4BzoBrC~v~#h}+g*{IUZM64tcYOp|v8dc(;Z1PtM!R@)>{ zWu&^jQZSPM`wy0|SV0|$Of$UW6+qLOPQw#SCr75u6@o*RWqp)^1r-sMY`z3kGm1pb z7R1zZ=6P=Od_-qxI&n74*B|Rdjd9_^j;GzKY)Y)(sA?E|c|!=;T$D;5ByCFHH}yv+ zNy=_mSmo?Zb_VVgU}W;BlEjn-bonL?zEgI~<0fh+J8phPn%L`R-lO>M^mMuz z;gPEHlTsWUw({eZgQ=`Ug?rCPsGigQV_B1t*e^z3D~;Al$SiYGy?31WnQ&1@Wzg_G zP}Aip+bk1uFfD1}8*=8XOjCAkA~fB4h=iIdZ-r;12Im{6fzi{nnqK zraHf5{4xEJRrWX-yg$P)1JBMKX_C01X$WxYU61%5+6I;RdBp!T8V8=Om*gMsr>xOd z_tgUj8V7zF#XnJQk(bZ<1^-iL)MgF8I2?<##+u0XgzqcG_XOUf{DPOQNSB~_YDXLe zG=~tU-jxtg@BGUP=3|r=5=*%+P*NFdD?5kqTc-VH=j{INL3N%4G%gi>;257~A+hlUZce+(ui?J%}Rmyn#oDIpcg!(A5)aLuEWDi`;*VbNqNrTQJjcR3bvSxrlUNg%jhQ0B*Jp z;>|ArLtIo;V+#Ke(YJjJ`ZH;I0VH=J^8lI!9)jQq> zRmo5=mAbW=%rWU^i!6Q)x)=+eK4O`rQ_}D#;nraj2oph^;pxIm-rKZOgI=&fPTmRO zE02VpHuGWrjQp^Gi6P-Vzt2e0kvV*X6XLB+eAwa+{)CqlC=$izNoz#$T0N}-Z?B|) zp0C0japLFnX$~L4?K^Ks=(B}TbwYbc&D8_ETkHs6LpG}c*8LGsNXnuEj%5hSTycTR zhXV;`9-a_%Ac3CNxKo={!gwP72bL|mjrkmB{uutgk zZCu&pQ#Sp1mOeC175-nodU}x8hI&=?$e*u1Ba0TwArg4Y)yz0MG$7SxP9)|)4`ubl z+$mb2Hj^d4IanY1?DZ<1VjC5*i|@1J=!&#$%w@*qYB{n;S43GuOR<>=wY@q-tV0nG zd+Ft(e3@R_eE`pQB=Hj?hv6BeXO3Mw*tYazejgjA@ozG~qcClSn;<%RJA(?AN#ft8 zMY+xu#ao;L+wGpO(le2>)hf709oCjuyx9NFry7kXum0fq?<({>4sOYc{uKh|MW6R5 zzEV$T2UE{(f%Q!S*eCQg@u3b)Q>kopse?tUqWE}$J?&03 zi_EUj4WCi`%lhE?$9ok2ik?ms!CvsZvS$^M zz?HC*U#%>?VPU?L=N2y5vd4hUn%fo)$_&T0%fdT(8Mc{x5U^rPUD!w1l?>XHVQ6ax(VP15-+3pyLYPiWKiq3;QaGUU$A?b^kN<=2Qfc`5IuNN3CpNwd>K@t{95 zhZPP+JEAqrKD8;U&AAEUv6Va~ORR8kPz`HB#KaJ1Kn{)^3Qphf5}OgqVBE1C@7D`Z zMkI%(=>UWGP0U z39<#9dmE51Y^cM;OZIF$Utp_uoDB(}{(({uI*pv29oA_$=#NVvu;(y_z^>IAEUw){ zbIh9?ROkZC$@rh|9!z9>_b^w`a;5k_$a@s8&@&u%Q)zB>*3;cR9SI(qn*YK?C4?tx z%?{CSV?#(UUMwjoqsUs#s#>*IAel=sAF^#l%m8dOAMn(qO6mEH71sbt>+cyH6@DE=S!@qhJf+D%dXS^e3@NV>PD zU88R#u}`Iy=**U`(#EdHh)op#gBO^gX=JgeqgngRO6VhHqI(JDy{!q8smh#ZQTz>8 zp)8Xq{+4@9Oc7@KWqNSdhVPpqvsVOXnIVE858mT9^Gd;gv6e#YOWf?0xMbAEFV1+) zG7xL4#I`XeTZAurrfo^hJfzGE36iyg&#>q5i?W8%VqTb0X_6ne=71+?XgWW%KRKs3 zh1|c?k~n-_cyKP!jE^|Oz68!*3H0OQ0*#A_G_nzcuy@wfY%!OZVO((7kVGD1LvmuI zNvNHXgD;-QfDz>-pqo7n1s_318k?(AeuhK<9JBp&vr4+$gP7w%aJ#skes^AWSq3(E za}OfNQT()E(C0mh=jquUClyxT0G`OfFFUDsp{w7#6}u$UesMLA2!~XJ)`x%`SF#he zGWE^C2q!lFX!WDh!S}+ZA$CzJaO|rf@Px?;u|zgO!P|?#;r?QE9M_o%A-e`x-XIi( ztv0qDB2j!bIJc4h>IA1T1h(!u3d8?8)X>Dk- zG1!#AK>^>YzgaUPoqm$asio6)z8E^tVInC(dj=C3Ppeue!$Z{}{)UCW!(@+IgZTTV zt6Q;V(d;k~D(x^~bz>@J%~Ob7%6s1$HvixQoDsg%p5hzUJ_^fA;|jO(9eYr)a~=CB z1LbA_)jD?dIfX5;;NjiwgvC$jj;u3{I}`lqvcoChbzT9BZpkMJ*{J@Qd7A|Y{|7Mv z9HYRY&iKkL5Xm3rY=^I)N>DSX7d-8ZSfr3^SnuR=9twgZqxiYPI`L3!OkXccUz`12 ztG_N)VO&xCeD~Vit^8vB8O3|`6zIHcJxvw)(;Ei$uEsoHzsgXhy=Ok-+9*a_-ZA#>VYQY09zd2UTc_q@#LkuP(4$ z3;P@AsRf}1h+>%PNtt1AcA5OxWB*s@EvdBs*Ho90QoOn(m=D{>B45($Z1RfJw3yS+ z6!-e>;-t8pYLOOirTNNKiw+D~Sg~41!6<&CqflZ^vE<}i>)Gh-sBmZqs-lQ*;o5}r zzDQo54+h|~gCHX?0fLLwA_iC!%AgvG`fAcuDF(V#&7vxm8R{tGThqF_;ri7LgJi|( zmej9qNuj!MAWv@+@}zG=#;`+;s+ZC?gX@QKEy^0#1mQ4Z6G7>Xfi~4-&62R-Wr-Dm zQX_bGLiS#>vxW6pY^^usvdvOiTrX)5*Ps+vHa;p4oe&uo=!@nd$Q&nt=Q*>C-DpLp z<&eH-b<4Aq;<}1-JU#gLYtEM<04Um(fEb&>%a5B9v;%Spb+%vo%11Q^In7^0@~y zPH`luC|_v&tbF}lFn00Y0&X`C_}Q}j%h)InRuA~mDL}K#%Z+5(V!K`nmhsaIa(kXq zyk6v8f$4fWdwoDJ(zSkWO^h&;`D}#n>^aLlypv{+i*^{-*f7f?g*Ekort3x8GF`ph zbcDe)+g<@>!bbET!MpxCF~WOsEZW{3rejPt2!O)-LufD&gq(I{KOA~ME(yTUG}4lv zTM^Hn)qMXJXg=Pfcu;wqXAlYU!u4JE>0UjX!sP?`k`=&zRPNpqCG49=P7oX|p_^ZO zisB40ppySLG>xl^6E^-rqd|+XS)b7|{&#-!x%}^RgrLvNJxD0N?}HX{`7t-pV3=rci{7L7<9a#-lP!0QT?8HD zo!lia1pD%M-=V#k<~{T?{*I2_a|PBmr?ERPibtD&vq4U$?)blZXe4E~Iw!PcQz%Pc ztje-|)?)eWz&u+xBaNe%IZX(9v&9*&ElXoW2C&=PUr~t10_tEN+YZN;R2iCv^uhqI z4(GnHgoImfP_8ok9M|b>u^ak7;Y_7;msQF`jk)698Sbfvaq@sj8R${oqjh zuL}XcafR)vc9^5w>T}o_6~!-bJn-8sho-5@yfc1J4ZCS9MW7y`&+9}JcIx_VIIsFt zqjAUR-~89BT5rR_b;C9sP9s|`NDZ~ghtCg9hta}A(~!!?r43D|0X%b{IkaHM4nITF z=9bdtP0=pv=ek-c7*w0hq)EMi+FVq~Jf38p&~G_JKjJb_TNH0~?@x2@thnhC2t9%P zYW*HCm-N4nowDGs2fy|zkIrwpLPaNO6u+55*&5#BGKV#QEH%6}t>H_bU-0Cc=YG9e z!`s`|@Jx&rjaUtW;_)y!-A2!ITd?X#)d$3v9-6ksG$z~(-RAC}@rt0yESg!}@O%myu zjNRsP_lr`kBO8tuznmX3U+%P7W~mcT?ZchOJQtQdprJF0tFI-xGY#Q_D9>)QjZR!~ zOtW^z2p71e(L{blgZL|W%gToFb^vKGp%F0jR9+5tDJNSoSd$-`rq(Eajcb~9@uXP3 ziuFOU0qKIYl5p|I3!5K>z5dHp5H9}sHmp}$+@S_he2d^W+Ykk9uznm82J%cvS4^sa z>9$-|6!&c@(v?M2E8Zlr6u648bDyG_FwH+L*(F9Ke7UIKf4OhHu z@KX$zT%gpPKD@ma=P#95J~+cAk4{POn*2RZ-91yPGKd;Pm!sFBc&R=lx_r5N&7231 z%*;Kw&^^gN_aO2T#cvZ(Ujgqe#Lk3jXqv(dvih}NBEt1M|0H8{@SY8_AkEo1G~LBb z_xmc$Pbj{I4jV>8@iiZxM=j&;^H;L`tBSb8q@(zo?$v_hLVvsYcx}>TL*5U3p`mH2 zgf3CcaUS_e0voFB7LaD}-b}sD*banLq~2%WzAuUNqU{B$lLOTWx+V~ao2NNGhV8i) zd~K5`JkWTaEe?^>d@Njuiz7MtXo+A1Gvw!~c}4@X^=TTW+FsIia`w>qQYAg^ylcO|oHtX4aLI=^WuAsKT{yUB|n zOz)~E=8BmqmjPL<5JwyFW;ecYGCDiYh<3;2pKRi%vFX`iNc(C2WZ&=TkE{;KpX{6c zdst)mLj4d(bFG?>G_so82?pO=?J_+gC;g^$KtP&wxOYZ$I7&}FPH90mY0{#eOk6D6 zigW9aYMH?rZ2*zwpjPY^4#b#hh1#hJL{4+D6UzNzz~{Nyt=}q;ggnf_ z{19w!p%ELKIa~^PF*8IjKjk((_~T4YJ6U*2e`0c;b|=(xVQlHu4yWA-#WJ~1yA%4j ze4MLplo5bcr`<_Aohx^>BZqy8;stX-0YnGy(L;jtH7BO|rzFy6EOUVE>sL1#XX%GB zS-W#+I&Y4(tJ2a3sJZ;fxm3KiHx*+HR;&2Z-c7j z-c-yasTz-8(VL1{DyvrUulA;5G)%RMZ|zORHs?aqlvN;a>`ldJ$!aZrOK&Ph7gwwJ zoxQ0TU0Y?^8nf1o!NGsIS__(Q#^76MvMgWmiE8mnd&6Ucm8J};vNX|`eYQ0l26Lxs1Kwcn_+&*Zxi*myy zkw%;ut4G;6}G|#t7MFBR{uZvZK}xxMzEQ?lv>5{kaFV_pH}`e-2S*FImy= z|A#X4o6X|jGmeqwX>Mv7Xva?5rRL`M=Z*+#G(lLnu(@E7wE}J{biS0tt#P*6a<YEA2R|zVx?F{J&`6!C@CFJ5n8aT}E>S0F^g7ocnLDmB}F9a!IhcGJw@E!uQPJl#k zPa)Svh+Mk#S$K!-m>ruk2x~)ZX4?UoQ9LMm6*eef%|tQI40F4A$JU<2w>u?zJ0j1) zeh?dr8HTeN29*zo6+S59Nv@M3SS4Ye62xZU1>q|KhKWyJ_A}Z^#{}V_kMz;I(ELWu zv~YR`@=UeWMhO_2%)?IPlzVnrl$&rJkZ#ST8~!#3&ZR+4>9{7RcB1ZtWSZDYZee5n z%H7C2G>vX5F5D6I!K&5Jbl^WbVE2rkfhR%#2!cCP?}?9$Dd44|qFqW7#S2}w!Bsjo zS8obM*V9G@ykG~;iQ+H0^!(Gs>J-)sM+DuU363U;;y-ur#NFgQia)9pr>f>CL%=_7 zs9_(yB<1OME8V*oId>oDttlNshwL`u9Zq2oAm&O8O;dSDqv9>AVM^o44!?Ifci!MC zHQL<|^8w>{kK#M@3_F7# zZwYJmVOfMahe!7Kl@PDf&R5sCK?-A6Qv)Bf(55lm@M1GnIMe&S@Ory%r z2~cEvJduqarp_Mkh|IGzk)!x=E<4siqe0h$)TN1x;gQw*`6ZihU1eaNa+hx>6RuC_ zhcf68RELEPRbIXsazILs6bBwBcTsC!WPX6)wC`NJ(v?b@i8;=E#WsN0c)P2`3}&%- zmY6zh=~(FuY~~^y@oZPcWAt!t8Zk}GU@*ivRFa$UxH_4?iCiM0iFu6Egbx$$g6nNW z3o7O`G;ZoHD4M4>l&s^9F$WFr2H?wx04s zqfC3DUT{Qt>f@;`Px)AMd9SDZ8v@GT>fU))rabcg-X`UblMa8cq~Cy-pnTqjGMgfb zS2>K%ch3vm)7cu>;N{!<3gPyqysg3PdT}pp4LoB)s@h;PfG4dN(txdT#f)r?5!YJ= z%vbatM{Dbk?{e=vD@%n@-VZrUwcaGDc&7sxNJSJ=AODKOPQ~dK24Z>1m@ka}T|ccV zt|*f5y?n*2Q~x_6$-Kk&V($A}qS;9g4Pg8ZLaU-s;>qcSP%`)3DD!unj>5lKhVN$0 z5--+X`qhn#^j_T@X07|%UU7ZWNs)=@$K5;6$|Cwo#|bZ@#us^w9l(r;QXl_{B3f}$ z;smQIPh>y#h9`NebZG^tMMX5dFn2f-8U6p>z4NS0e^z_iT!m)Y@U^g4S8>A5*vMd%ONE8&(|V0YsoWKK2?bg zVP4US*#G8;&9gMIqxc_Pp>McnX-Td)&~Y|ud0`@$qen50=TxeAo(TIk{eW!VjZjf< zKHH#F?7Qcx)QrVR19hl3hvj}8sX%>}2tMMa>nBbuOmF_5d*@kNy8K9mF8)ZSD}O{? z*?{+6Z?39EdkJ07X>ZqJl$U&H|9VgRM=AQ-yU-rt-g(xd{p&Ndf4yjLzor1w;m zd(FURPJ3%qd151!zuJn}k9Wl8S&P^&6?so`APyCg&#NWiYkNWDoN{4@^|A`eg~-IF za+&XlWXdIS?>sBh9GIz(n7=+D4jAy>3;6l9XitbT#;$gbd%lq@3!RuP+>I%N9+$9A5T+0K;x6HQydf`bZ9V~iHRlF{1$ zvCC>v|MDY2eLCI!tvcPWIqLJQOnsB%u+!aNblKDCyvx3~)W4z@^@+tg?6QA~sNW1% z2xb2rj`}<+Qy<6h+nTa(ex#i2vp0j&fJ>>oir%K@)uR6MdqMqND~ZbI7_Rao5QhUa z+3_LA0%OV_xp$tG*}>TkDLZf-zfIPL0q^~QbCu{=zP)%ij}b;mB3i zvSnd=!VfnT^)kS?BP!|0h`0GZ4k?vgmP-ceeYuunzR9_P+)q^fnEuSM&Ep2*=CanKQ&XJsNY zDx4)EqqQn@p^8M_R*T5j_JYVchdjreRDqY&h1v^Q=sB_P>lY$7RNd z5pm#n2e8B#QBi$u7ZtmxFSw(B2ec@QH=;);f4xW`%U67{DsFeySw(5Pj>c4W9_~<~ z9_Y<#U791u);7gUo+&S0PjS+~v$A**{(#>6AJYnR0a`+=DiV2TEh6ta5=3S=KC2ax z&u~QMS((W6le3zA*n~GX)#IFnm1Uhd6$2D^I|(mq;Ih~E?=_eDMx7McczTX|=UG`IaPOr{eYp2ni!$K7?|ysh(0*WFk7)lm z!MRYOu4@zrdS$KXPek%u-zT3NaA2K#=UJHpUd-F9|3xwN@NdSJ`IJGaXqjKHQZpW5 zS|}MdLzb6)oNp(3%5M%Rf0cXZS();{ynoai?))`RvTwk9FZ(ytqW+D&puRP#JhAbm z-ancwbBDx!ks~(G%EV@ddH<;PML7_qiCocayh-FL-%dRC$LXgBeQUo#so1w(qEa*N zTV{NfZ#9B`obO8EgzOg_Yk1b;?r}}S!suG)^UJkG=+L1<1 z=UJKhmpYhUkugy_PKvDb)U2Wn{jyrb{>39fY)CP$m8k!gBR0>{#E#a)K4d@DypGlgq4U@am1Bh;qZ^Rc!-*3V1;KW{I%01JWHz~ujQG_zp^>v;w*Tj zbpFR2z>M+QS_CQ*Th8q2#2%0N2HdT`)ER9f5Fj)XJukrPtzUu4n%>- zc2GrYLRVD7s-Qw!jqR-~uE=4IRZ-0qyA#K-9Cia16Y5q!s)u_p|HZL~XJrnvY;$X~ zJF&iStGd%C9l+jqCr*d2Ol)`VV-JW8#maZ5`RY#1J%AyxzvpPfvof*iPLTIM9Ebvu zMR%dt6RGCly2^xZu+eJ9gf2{fmTK}dT!HckVRO{@i6fQG*8b1E^Q=sHx=uQ3SPj~; z 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 literal 209136 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 diff --git a/FluxEngine.cydsn/UdbSampler/UdbSampler.cyudb b/FluxEngine.cydsn/UdbSampler/UdbSampler.cyudb index ead7a66bc6ae98fe52d2579eb82663b341f15541..457f8ac7512dd4ecd49ce1dcc33b372653dea6d9 100644 GIT binary patch delta 6752 zcmb7I2~?Cv68@_N2AB&N5IN)=(2SsB(EQOv(IoqfN!BwMh2l%2YBkj`+NGR`l`OF>i!S) z5AT}=KD&C`SQ*%JSj)1Bw$ezrRi^LnZ-%h4mM^z%&$?%n^<6rsnb%Jvm{Fvc^OM!{ugR$6*NzP;*)j`oy_c+V&$N6E3z zsc3^KX0VlgU%_6-8T}zu^>`7c0v_*2-O~Q>g%xh#hkt@-d}liBRa0lc0bgYALkmp* z8|ZLZCM2WB`_Nnr?R$S|XOB|7@XlM{6?jFjC{~AiYmdGiWghtu@)V z|GF;(JLSTBrWo*|4}?QAT(uB_8}qZL-S-N)FNhfpTv?KoeIt&`gIN&)VnOneecnPX z{gFK0&4WB<5OxGP@NaDEDda-Ywg`HMxI)&55aus}H4ui8??6k4XaYXO>2MPi{PQ6k z+bn_@6p5-Q;0mB?1`8HJ!UrULA%p5Kvjn_w$zn)>cr0H`W}j=q?2}U#iV67;`~Rfu z&b#ogXEKp!hW;@S0x3<{d@|LsRu`T6AlA<~bJmgPEZm;-dmQF21`j-+4_!UexLJG8 zlOfPk?N9)7z$24paQEM#rG3ht9y&g11TnbritO3p0 z5FX;TuGPR9Ye@E^WiXIUHsGaf=z>Yhp-|tCgrY7)U9dVP;IZXkHT4%-14WU(N|HP1 zjEMRe+Tja@uoBK;@)EFwk!wOsw!<}j;c}|ii3~+Kk%9gzA@B)4k^h77zzXQ4Kb8Tx zN-kA+&a)61k0mQ1Nq^dx9~7RpkZbmu?4hSf>?7utK)SIw>Jg1z8LmC zTr++k7G%2ujdn<5g|xmBI$*9HicBS9J(}^PEHmKaO%N)BGW!E44S8ZL!g0`QNO^J) zirCI)p}h{ftN{bw&ZcbiK}z1{I*xnr0z!zXR6}sPHhBZrKHX0$vrwF}8bY7!>|p%I zhg3!1K8weraqC~9J3HyjPvkl%Y+qjI^gpQ=TiK6pYt5XO)iKJ4$M}eb$5CgZ;@4B6 zE{g@({){b(C{dNpL@h0X&rNs4x=hr0k*F83sF)P1#e!@f;))HV_`s>iN?@tU%gF6Y z#d}W0t0kluAQoh6#IqYo(O{IN@!}@fYK+h*`l>aXpdGZgi8nzgmd zGCsDQ%OK`_n6>)djBU66g`+n^2(vnYw{M2t*lr>C;OpLWN<-mI*GR! zm>=G-LwtBv)_&5x=(3urvD#Hy{c0;&eMQX6HVgNCMDZE!L~Xqd`qH^RV;gieYU4YU ztB0s3w?P~{ZS#nt?Dfghi}L6vRFrd#&u|Qm#ZR`w^K3qO$&bP49Z;A&l~~AQa31w! zQR?c7GG7#BwqPnx#@Xt{9gqmd6=F`dOE7dNu`h74U%nIiGB2Y&`H^kSE-<@A;5`vQ zh{NJyxH_;@fXH?u^|j@qD0!5HmtEzeBUed*b! zYWOaQZU)!Xv@$r_%-hSv_v<%$`>N$Z7^6arPR<<1BV}O0(JBO({v%vc;4w-5$A~jO zhY;^a0<*@5CA;7+81xxz&^f2n&p!hlSokQmQYtxDuwp+XcsCOkJxu6x0A>a9kxQ&@ zWyJv)56#tk2VlF0_cS42WyCvQKx^#r8<^C}a!54meiaLM(eDHd^R5pY3{xsO28i$;Qp20x7SypT z2Q|tEO)>^Y1jv^r9)nPveFh%toKxzIA9xJ-$VJY%f=eo(ONfO`!QW2B7Oa?dwyF7)2BPcFLPCS7inCzrqqxNP=JWE;>D+ znFVerTB7M16i(EW5cuVe(u6Bo5Lp%V(efeye$|1r5q?uNXv)nMEuk!D6w9tdyvaQf zYSneP0T#ZaUAc4Z?#nk|0qxNBH))II+=NKkkML?o#^{}ypHk|XoA4zwr_+o}oBH-k z6GPQQ|AtC0n1DlkSRn4a50gzJHBuw}?CI0O)U*e13jA_~_f>Rk=^ub+HQa1#dEb-neMpu31S##(Qh=RR%;Sb0(t<`|9_2Z|6Ma_H!ZGi;l*T4v! zR6U00YaqkIQC$wZEF?XK6lQd2Rvi0gvX_|gwr1+KTEW;`UZ6*aC0>(!Sh|V%*Ml*C zEc0Q@E#YEL?(F8`!EG-N^JSf39xn4`Z?QOk^wG2D>HfLVpGDvVJsTVtM>4Lrplu%wuLQwM>P68!?Iow%W5v6d)gMQh7Z;w#{tTmRjVF8eay8|eNJN%fTYg!{((rI^E zbH$xEQ^-1*4#4|8CrZoq|=qJFD;@VzouEn#oyphAooNjUaZK6ACb`p;f9gSt#RVH2Iv>F-~B~9VaVO zBDvem5q38V*}4?A3MRXU1xmS0;htbh;bCd~elQyixjcV1EHblzurVZA=ffWDV67;r zp{|>b@t)Peg{=-QWp%8jHnvjhqBQF6;JJtd(jB zXNNpIX~!vgOgaQX>g^~N#F%dYuD?&;zz#<-Bidrw5L2y2yVjqdzhcqPvzm0tvFX%W z9pV1!kythdbnyXvScTo=*hW~57vfkE?85o+EP~2-eLU+%KZ9*74Ki_sjg9CzkIo&4 zy5J(XPn-ei1k&mptth~6TYZ$*m1*?L|1S36#_A3C!JVyGh;EoLyG&MfRV%9MVbaVr zVJ6i|DjGBLyM|O6LaOqQW6PsTl1dZU-jf9Od-5dGKS$V;B(_yz^R2DHmT!Dg$sJps z7ZQ7o#GWg#yK?LxOtew`%$3;r5}VhY23x+2N+ow}Ue2y$ye6>=1olvgJ){j`7idGD z%J-25Tly`P+_B~6lz!*Rc&`)K=Vjf`Ng(WX61!ab%}*W;w){LHmE5s&HGc1re(w<2 zG1Bi36A62V#NI5id68?dj>5EB`1spO8GuE8EB{k|fwi@D#y^uado1U*t*tca-Q4CAzFbTZ6dBH&m(Sj=om?Dv4Dw*3yF8JFvOT zV#YC@StlHo!q$1VC1UikH-$E=)xq;72Od^Oiobj^e5oTl%e;ru7b2@8(t`6lvKViE OFj^fJvr0fCJ^u$CE}*Rd delta 6142 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 Date: Fri, 12 Jul 2019 23:09:50 +0200 Subject: [PATCH 3/5] Show the clock rate in kHz as well, because that's more useful. --- lib/reader.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/reader.cc b/lib/reader.cc index b664d36a..b2285c39 100644 --- a/lib/reader.cc +++ b/lib/reader.cc @@ -160,8 +160,9 @@ void readDiskCommand(AbstractDecoder& decoder, const std::string& outputFilename track->rawrecords.size(), track->sectors.size()); if (track->sectors.size() > 0) - std::cout << fmt::format("{:.2f}us clock; ", - track->sectors.begin()->clock / 1000.0); + std::cout << fmt::format("{:.2f}us clock ({:.0f}kHz); ", + track->sectors.begin()->clock / 1000.0, + 1000000.0 / track->sectors.begin()->clock); for (auto& sector : track->sectors) { From 973f4c2c2df961b9238a9248ee98450584bdde5e Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 3 Aug 2019 22:30:30 +0200 Subject: [PATCH 4/5] Skeleton work to factor out the encoder logic. --- lib/brother/brother.h | 6 ++++++ lib/brother/decoder.cc | 1 + lib/brother/encoder.cc | 1 + lib/{encoder.cc => encoders/encoders.cc} | 0 lib/encoders/encoders.h | 7 +++++++ mkninja.sh | 2 +- src/fe-readbrother.cc | 1 + src/fe-writebrother.cc | 1 + 8 files changed, 18 insertions(+), 1 deletion(-) rename lib/{encoder.cc => encoders/encoders.cc} (100%) create mode 100644 lib/encoders/encoders.h diff --git a/lib/brother/brother.h b/lib/brother/brother.h index 05435258..3c88b30a 100644 --- a/lib/brother/brother.h +++ b/lib/brother/brother.h @@ -22,6 +22,12 @@ class BrotherDecoder : public AbstractDecoder void decodeDataRecord(); }; +class BrotherEncoder : public AbstractEncoder +{ +public: + virtual ~BrotherEncoder() {} +}; + extern void writeBrotherSectorHeader(std::vector& bits, unsigned& cursor, int track, int sector); extern void writeBrotherSectorData(std::vector& bits, unsigned& cursor, diff --git a/lib/brother/decoder.cc b/lib/brother/decoder.cc index 46420deb..18c0a354 100644 --- a/lib/brother/decoder.cc +++ b/lib/brother/decoder.cc @@ -3,6 +3,7 @@ #include "fluxmap.h" #include "decoders/fluxmapreader.h" #include "decoders/decoders.h" +#include "encoders/encoders.h" #include "record.h" #include "brother.h" #include "sector.h" diff --git a/lib/brother/encoder.cc b/lib/brother/encoder.cc index 412a3709..8219caf2 100644 --- a/lib/brother/encoder.cc +++ b/lib/brother/encoder.cc @@ -1,6 +1,7 @@ #include "globals.h" #include "record.h" #include "decoders/decoders.h" +#include "encoders/encoders.h" #include "brother.h" #include "crc.h" diff --git a/lib/encoder.cc b/lib/encoders/encoders.cc similarity index 100% rename from lib/encoder.cc rename to lib/encoders/encoders.cc diff --git a/lib/encoders/encoders.h b/lib/encoders/encoders.h new file mode 100644 index 00000000..50105621 --- /dev/null +++ b/lib/encoders/encoders.h @@ -0,0 +1,7 @@ +#ifndef ENCODERS_H +#define ENCODERS_H + +class AbstractEncoder {}; + +#endif + diff --git a/mkninja.sh b/mkninja.sh index 4a8dae08..33f4a2b6 100644 --- a/mkninja.sh +++ b/mkninja.sh @@ -150,7 +150,7 @@ buildlibrary libbackend.a \ lib/decoders/decoders.cc \ lib/decoders/fluxmapreader.cc \ lib/decoders/fmmfm.cc \ - lib/encoder.cc \ + lib/encoders/encoders.cc \ lib/f85/decoder.cc \ lib/fb100/decoder.cc \ lib/flags.cc \ diff --git a/src/fe-readbrother.cc b/src/fe-readbrother.cc index 0f701ee2..0c1a9d6b 100644 --- a/src/fe-readbrother.cc +++ b/src/fe-readbrother.cc @@ -3,6 +3,7 @@ #include "reader.h" #include "fluxmap.h" #include "decoders/decoders.h" +#include "encoders/encoders.h" #include "brother/brother.h" #include "sector.h" #include "sectorset.h" diff --git a/src/fe-writebrother.cc b/src/fe-writebrother.cc index 42dc5e2b..1e6dee95 100644 --- a/src/fe-writebrother.cc +++ b/src/fe-writebrother.cc @@ -4,6 +4,7 @@ #include "sector.h" #include "sectorset.h" #include "decoders/decoders.h" +#include "encoders/encoders.h" #include "brother/brother.h" #include "image.h" #include "writer.h" From 5748f017ddb06bb6d6e3e0ef3ecdc3aa9691d0e3 Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 6 Aug 2019 22:17:58 +0200 Subject: [PATCH 5/5] Refactor the write code to make it easier to add new encoders. --- lib/brother/brother.h | 11 +++-- lib/brother/encoder.cc | 78 +++++++++++++++++++++++++++++++++++- lib/encoders/encoders.h | 13 +++++- lib/writer.cc | 22 +++++++++- lib/writer.h | 4 ++ src/fe-writebrother.cc | 89 ++--------------------------------------- 6 files changed, 124 insertions(+), 93 deletions(-) diff --git a/lib/brother/brother.h b/lib/brother/brother.h index 3c88b30a..73313486 100644 --- a/lib/brother/brother.h +++ b/lib/brother/brother.h @@ -9,6 +9,9 @@ #define BROTHER_DATA_RECORD_CHECKSUM 3 #define BROTHER_DATA_RECORD_ENCODED_SIZE 415 +#define BROTHER_TRACKS_PER_DISK 78 +#define BROTHER_SECTORS_PER_TRACK 12 + class Sector; class Fluxmap; @@ -26,11 +29,11 @@ class BrotherEncoder : public AbstractEncoder { public: virtual ~BrotherEncoder() {} + +public: + std::unique_ptr encode(int physicalTrack, int physicalSide, const SectorSet& allSectors); }; -extern void writeBrotherSectorHeader(std::vector& bits, unsigned& cursor, - int track, int sector); -extern void writeBrotherSectorData(std::vector& bits, unsigned& cursor, - const Bytes& data); +extern FlagGroup brotherEncoderFlags; #endif diff --git a/lib/brother/encoder.cc b/lib/brother/encoder.cc index 8219caf2..20911866 100644 --- a/lib/brother/encoder.cc +++ b/lib/brother/encoder.cc @@ -4,6 +4,35 @@ #include "encoders/encoders.h" #include "brother.h" #include "crc.h" +#include "sectorset.h" +#include "writer.h" + +FlagGroup brotherEncoderFlags; + +static DoubleFlag clockRateUs( + { "--clock-rate" }, + "Encoded data clock rate (microseconds).", + 3.83); + +static DoubleFlag postIndexGapMs( + { "--post-index-gap" }, + "Post-index gap before first sector header (milliseconds).", + 1.0); + +static DoubleFlag sectorSpacingMs( + { "--sector-spacing" }, + "Time between successive sector headers (milliseconds).", + 16.2); + +static DoubleFlag postHeaderSpacingMs( + { "--post-header-spacing" }, + "Time between a sector's header and data records (milliseconds).", + 0.69); + +static StringFlag sectorSkew( + { "--sector-skew" }, + "Order in which to write sectors.", + "05a3816b4927"); static int encode_header_gcr(uint16_t word) { @@ -41,7 +70,7 @@ static void write_bits(std::vector& bits, unsigned& cursor, uint32_t data, } } -void writeBrotherSectorHeader(std::vector& bits, unsigned& cursor, +static void write_sector_header(std::vector& bits, unsigned& cursor, int track, int sector) { write_bits(bits, cursor, 0xffffffff, 31); @@ -51,7 +80,7 @@ void writeBrotherSectorHeader(std::vector& bits, unsigned& cursor, write_bits(bits, cursor, encode_header_gcr(0x2f), 16); } -void writeBrotherSectorData(std::vector& bits, unsigned& cursor, const Bytes& data) +static void write_sector_data(std::vector& bits, unsigned& cursor, const Bytes& data) { write_bits(bits, cursor, 0xffffffff, 32); write_bits(bits, cursor, BROTHER_DATA_RECORD, 32); @@ -90,4 +119,49 @@ void writeBrotherSectorData(std::vector& bits, unsigned& cursor, const Byt write_byte(0); } +static int charToInt(char c) +{ + if (isdigit(c)) + return c - '0'; + return 10 + tolower(c) - 'a'; +} + +std::unique_ptr BrotherEncoder::encode( + int physicalTrack, int physicalSide, const SectorSet& allSectors) +{ + if ((physicalTrack < 0) || (physicalTrack >= BROTHER_TRACKS_PER_DISK) + || (physicalSide != 0)) + return std::unique_ptr(); + + int bitsPerRevolution = 200000.0 / clockRateUs; + const std::string& skew = sectorSkew.get(); + std::vector bits(bitsPerRevolution); + unsigned cursor = 0; + + for (int sectorCount=0; sectorCountdata); + } + + if (cursor > bits.size()) + Error() << "track data overrun"; + fillBitmapTo(bits, cursor, bits.size(), { true, false }); + + // The pre-index gap is not normally reported. + // std::cerr << "pre-index gap " << 200.0 - (double)cursor*clockRateUs/1e3 << std::endl; + + std::unique_ptr fluxmap(new Fluxmap); + fluxmap->appendBits(bits, clockRateUs*1e3); + return fluxmap; +} diff --git a/lib/encoders/encoders.h b/lib/encoders/encoders.h index 50105621..046a950d 100644 --- a/lib/encoders/encoders.h +++ b/lib/encoders/encoders.h @@ -1,7 +1,18 @@ #ifndef ENCODERS_H #define ENCODERS_H -class AbstractEncoder {}; +class Fluxmap; +class SectorSet; + +class AbstractEncoder +{ +public: + virtual ~AbstractEncoder() {} + +public: + virtual std::unique_ptr encode( + int physicalTrack, int physicalSide, const SectorSet& allSectors) = 0; +}; #endif diff --git a/lib/writer.cc b/lib/writer.cc index 5f52441d..b497732d 100644 --- a/lib/writer.cc +++ b/lib/writer.cc @@ -6,9 +6,14 @@ #include "protocol.h" #include "usb.h" #include "dataspec.h" +#include "encoders/encoders.h" #include "fluxsource/fluxsource.h" #include "fluxsink/fluxsink.h" #include "fmt/format.h" +#include "record.h" +#include "image.h" +#include "sector.h" +#include "sectorset.h" FlagGroup writerFlags { &hardwareFluxSourceFlags }; @@ -60,10 +65,12 @@ void writeTracks( { if (!outdb) { - std::cout << "erasing" << std::endl; + std::cout << "erasing\n"; usbSeek(location.track); usbErase(location.side); } + else + std::cout << "skipping\n"; } else { @@ -96,3 +103,16 @@ void fillBitmapTo(std::vector& bitmap, } } +void writeDiskCommand( + AbstractEncoder& encoder, const Geometry& geometry, const std::string& inputFilename) +{ + SectorSet allSectors; + + readSectorsFromFile(allSectors, geometry, inputFilename); + writeTracks( + [&](int track, int side) -> std::unique_ptr + { + return encoder.encode(track, side, allSectors); + } + ); +} diff --git a/lib/writer.h b/lib/writer.h index ad331dcb..38232d7e 100644 --- a/lib/writer.h +++ b/lib/writer.h @@ -6,6 +6,8 @@ extern FlagGroup writerFlags; class Fluxmap; +class AbstractEncoder; +class Geometry; extern void setWriterDefaultDest(const std::string& dest); @@ -15,5 +17,7 @@ extern void fillBitmapTo(std::vector& bitmap, unsigned& cursor, unsigned terminateAt, const std::vector& pattern); +extern void writeDiskCommand( + AbstractEncoder& encoder, const Geometry& geometry, const std::string& inputFilename); #endif diff --git a/src/fe-writebrother.cc b/src/fe-writebrother.cc index 1e6dee95..34369a68 100644 --- a/src/fe-writebrother.cc +++ b/src/fe-writebrother.cc @@ -1,109 +1,28 @@ #include "globals.h" #include "flags.h" -#include "fluxmap.h" -#include "sector.h" -#include "sectorset.h" #include "decoders/decoders.h" #include "encoders/encoders.h" #include "brother/brother.h" -#include "image.h" #include "writer.h" #include "fmt/format.h" +#include "image.h" #include -#include -static FlagGroup flags { &writerFlags }; +static FlagGroup flags { &writerFlags, &brotherEncoderFlags }; static StringFlag inputFilename( { "--input", "-i" }, "The input image file to read from.", "brother.img"); -static DoubleFlag clockRateUs( - { "--clock-rate" }, - "Encoded data clock rate (microseconds).", - 3.83); - -static DoubleFlag postIndexGapMs( - { "--post-index-gap" }, - "Post-index gap before first sector header (milliseconds).", - 1.0); - -static DoubleFlag sectorSpacingMs( - { "--sector-spacing" }, - "Time between successive sector headers (milliseconds).", - 16.2); - -static DoubleFlag postHeaderSpacingMs( - { "--post-header-spacing" }, - "Time between a sector's header and data records (milliseconds).", - 0.69); - - -static StringFlag sectorSkew( - { "--sector-skew" }, - "Order in which to write sectors.", - "05a3816b4927"); - -static int charToInt(char c) -{ - if (isdigit(c)) - return c - '0'; - return 10 + tolower(c) - 'a'; -} - int mainWriteBrother(int argc, const char* argv[]) { setWriterDefaultDest(":d=0:t=0-77:s=0"); flags.parseFlags(argc, argv); - SectorSet allSectors; + BrotherEncoder encoder; Geometry geometry = {78, 1, 12, 256}; - readSectorsFromFile(allSectors, geometry, inputFilename); - - int bitsPerRevolution = 200000.0 / clockRateUs; - std::cerr << bitsPerRevolution << " bits per 200ms revolution" << std::endl - << fmt::format("post-index gap: {:.3f}ms\n", (double)postIndexGapMs); - - const std::string& skew = sectorSkew; - - writeTracks( - [&](int track, int side) -> std::unique_ptr - { - if ((track < 0) || (track > 77) || (side != 0)) - return std::unique_ptr(); - - std::vector bits(bitsPerRevolution); - unsigned cursor = 0; - - for (int sectorCount=0; sectorCountdata); - } - - if (cursor > bits.size()) - Error() << "track data overrun"; - fillBitmapTo(bits, cursor, bits.size(), { true, false }); - - // The pre-index gap is not normally reported. - // std::cerr << "pre-index gap " << 200.0 - (double)cursor*clockRateUs/1e3 << std::endl; - - std::unique_ptr fluxmap(new Fluxmap); - fluxmap->appendBits(bits, clockRateUs*1e3); - return fluxmap; - } - ); + writeDiskCommand(encoder, geometry, inputFilename); return 0; }