<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><id>http://aneviltrend.com</id><title>An Evil Trend</title><updated>2009-11-25T12:00:11-05:00</updated><link href="http://aneviltrend.com" rel="alternate"/><link href="http://aneviltrend.com/atom.xml" rel="self"/><author><name>Devrin Talen</name></author><entry><id>http://aneviltrend.com/archive/and_i_thought_html_was_supposed_to_be_a_real_markup_language.html</id><title>And I Thought HTML Was Supposed to Be a Real Markup Language</title><updated>2009-07-31T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;Every time I compile some C code I write I get &amp;#8211; and I counted to make sure
   &amp;#8211; approximately 43 million errors, all of which are nagging me about
   unbalanced parentheses and forgotten semicolons. And every time I gesticulate
   violently and sternly address the screen, &amp;#8220;If you&amp;#8217;re so smart &lt;em&gt;you&lt;/em&gt; fix it!&amp;#8221;
&lt;/p&gt;
&lt;p&gt;Which is, to say, that the compiler doesn&amp;#8217;t allow room for error. And it
   shouldn&amp;#8217;t, either. As soon as the compiler tries to be smarter than you are &amp;#8211;
   mind you, it &lt;em&gt;is&lt;/em&gt; &amp;#8211; and starts fixing your mistakes, it&amp;#8217;ll inject some really
   mind-blowingly stupid code that&amp;#8217;ll leave you scratching your head and wondering
   why you didn&amp;#8217;t just fix it in the first place.
&lt;/p&gt;
&lt;p&gt;What I&amp;#8217;m left wondering is why browsers accept bad code. They&amp;#8217;re parsing a
   language with syntax and specifications and all the paperwork to be a
   legitimate language, yet they willfully drop into &amp;#8220;quirks&amp;#8221; mode to handle
   malformed HTML. And the result is predictable: ordinary people don&amp;#8217;t give a
   hoot if their pages are valid because who the heck cares? It renders just fine,
   doesn&amp;#8217;t it?
&lt;/p&gt;
&lt;p&gt;Why, if my compiler doesn&amp;#8217;t, should my browser bend over backward to render
   pages that are invalid? No programmer would expect invalid code to compile, and
   yet here we are, something like a decade after HTML was introduced, still
   treating it as a baby. Can I say something? HTML is &lt;em&gt;dead simple&lt;/em&gt; to write.
   There are like two rules: every opening tag needs a closing tag, and some tags
   &amp;#8211; such as &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; &amp;#8211; need specific attributes. Compare that to C, Python,
   Java, etc. This isn&amp;#8217;t rocket science.
&lt;/p&gt;

&lt;h2&gt;The History of Quirks&lt;/h2&gt;
&lt;p&gt;&amp;#8220;Quirks&amp;#8221; mode harkens back the dark days of the internet. Fledgling web
   developers (read: pubescent teenagers fiddling on Angelfire) were crafting 
   Web 1.0, replete with Tomb Raider walkthroughs and &lt;a href=&quot;&quot;&gt;Real Ultimate Power&lt;/a&gt; 
   (which, as an aside, is still &lt;em&gt;hilarious&lt;/em&gt;). And these pioneers had no time for
   &amp;#8220;syntax&amp;#8221; or &amp;#8220;rules&amp;#8221;. How could they? Fueled only by &lt;em&gt;raw vision&lt;/em&gt; and Tang the
   internet was born.
&lt;/p&gt;
&lt;p&gt;Corporations were taking notice. &amp;#8220;Why,&amp;#8221; they said, &amp;#8220;we could use this
   newfangledness for intranets.&amp;#8221; And they promptly tasked the most capable
   employees: the aging site admins whose jobs were slowly being replaced by
   computers. Well, if you can&amp;#8217;t beat them &amp;#8211; you know.
&lt;/p&gt;
&lt;p&gt;And there were the visionaries. We all know them. They were the darlings of
   Wall Street: &lt;a href=&quot;http://ebay.com&quot;&gt;eBay&lt;/a&gt;, etc. These men and women were going to change the
   world. On their Herman Miller aerochairs they gazed into their crystal balls
   and revealed to the world its fate, largely a concoction of digital money,
   internet grocery stores, and beanie babies. The world had enough by 2000, but
   the bubble boys had left their mark(up. Ha!).
&lt;/p&gt;
&lt;p&gt;The browsers of the time &amp;#8211; Netscape and Internet Explorer &amp;#8211; were playing
   second fiddle to the internet. Success was black and white: either you render
   the web, or the other guy does. If Joe here sees a jumbled mess at
   &lt;code&gt;joeisawesome.com&lt;/code&gt; with Netscape he&amp;#8217;ll do what&amp;#8217;s rational: curse loudly and
   open up Internet Explorer.
&lt;/p&gt;
&lt;p&gt;And in that dark race quirks mode came to light.
&lt;/p&gt;

&lt;h2&gt;What Quirks Mode Means Today&lt;/h2&gt;
&lt;p&gt;Quirks mode means that people don&amp;#8217;t care. Validating your site is like extra
   credit on a test. Only that kid with the huge glasses is going to care if he
   gets it right. Yeah, we&amp;#8217;ll try it, but we&amp;#8217;re too cool to care.
&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s already a &lt;a href=&quot;&quot;&gt;lot of discussion&lt;/a&gt; on the subject and it&amp;#8217;d be redundant
   to bring it up. Suffice it to say that the way browsers handle code today is
   &lt;em&gt;not good&lt;/em&gt;.
&lt;/p&gt;

&lt;h2&gt;A Modest Proposal&lt;/h2&gt;
&lt;p&gt;Kill quirks mode.
&lt;/p&gt;
&lt;p&gt;But seriously.
&lt;/p&gt;
&lt;p&gt;We can&amp;#8217;t leave out half the web, can we? There&amp;#8217;s a lot &amp;#8211; &lt;em&gt;a lot&lt;/em&gt; &amp;#8211; of
   content out there that&amp;#8217;s not valid HTML. And never will be. This is content
   that people rely on: popular websites, corporate intranets, your website
   works-in-progress. And cutting out the quirks mode of every browser would mean
   alienating a lot of people and making life much harder for others. We can&amp;#8217;t
   realistically say that cutting out quirks mode is a good thing (though it&amp;#8217;s
   what I&amp;#8217;m personally rooting for). Not to mention that it&amp;#8217;ll &lt;em&gt;never happen&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;But what if Google didn&amp;#8217;t index invalid HTML?
&lt;/p&gt;
&lt;p&gt;(Giving higher priority to valid over invalid HTML would have a similar
   effect.)
&lt;/p&gt;
&lt;p&gt;Google has a very large stick with which to brandish: if you&amp;#8217;re not on Google&amp;#8217;s
   search results, you&amp;#8217;re not on the internet. Plain and simple. Companies know
   this and already invest heavily in search engine optimization. Turn web
   standards into an SEO strategy and you&amp;#8217;ll have even the most remote corners of
   the web evangelized.
&lt;/p&gt;
&lt;p&gt;How could we ever get Google to drink the Kool-Aid and actually pull this off?
   I haven&amp;#8217;t the slightest clue. It&amp;#8217;s a pie-in-the-sky dream. But it could work.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/and_i_thought_html_was_supposed_to_be_a_real_markup_language.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/introduction_to_groff.html</id><title>Introduction to Groff</title><updated>2008-10-04T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;Groff is the GNU implementation of AT&amp;amp;T&amp;#8217;s &lt;code&gt;troff&lt;/code&gt; and associated programs
   (&lt;code&gt;pic&lt;/code&gt;, &lt;code&gt;table&lt;/code&gt;, etc.). It&amp;#8217;s a typesetting language much like LaTeX.
&lt;/p&gt;
&lt;p&gt;But who cares! Here&amp;#8217;s the canonical &lt;code&gt;helloworld.ms&lt;/code&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.TL
Hello World
.AU
Devrin Talen
.AI
Awesome, Inc.
.AB no
.AE
.PP
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
est laborum.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compile this into something useful with
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% groff -ms -P-pletter helloworld.ms | ps2pdf - helloworld.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Groff&amp;#8217;s &lt;code&gt;info&lt;/code&gt; page is chock full of good documentation and should be your
   first resource for learning how to use it. But here are the rough strokes:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;p&gt;Lines that begin with &lt;code&gt;.&lt;/code&gt; characters specify macros. For example, the &lt;code&gt;.TL&lt;/code&gt;
   macro sets up everything that follows as title text. The &lt;code&gt;.AU&lt;/code&gt; macro
   changes that to a different font for listing author names.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Unlike LaTeX, which uses &lt;code&gt;begin&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; statements to enclose sections,
   groff uses macros to switch up the formatting until the next macro is
   specified.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Everything has to be processed in one pass of the source document. This
   means that tables, figures, etc. will all be positioned where you specify
   them in the source, unlike LaTeX which will do its best to find a good
   spot. (Also &amp;#8211; groff won&amp;#8217;t generate a bunch of temporary files and clutter
   stuff up)
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;#8217;s a venerable and time-tested typesetting language should be a part of
   anyone&amp;#8217;s typesetting arsenal.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/introduction_to_groff.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/i_hate_twitter_and_yes_thank_you_i_did_take_my_pills_this_morning.html</id><title>I Hate Twitter and Yes, Thank You, I Did Take My Pills This Morning</title><updated>2008-07-30T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;Three weeks ago I pulled the plug on my &lt;a href=&quot;http://twitter.com&quot; title=&quot;Twitter home page&quot;&gt;Twitter&lt;/a&gt; account. Almost a year
   ago I had fallen head over heels for that service, and when I finally cut the
   cord I felt as if I had pulled my head out of the internet&amp;#8217;s ass and took a
   breath of fresh air.
&lt;/p&gt;
&lt;p&gt;Twitter is the cool kid&amp;#8217;s table all over again. It&amp;#8217;s a positive-feedback system
   that perpetuates the position of those with the most followers and steals the
   lunch money from the nerds. Sour grapes, I know. But hear me out.
&lt;/p&gt;

&lt;h2&gt;Meet Devrin&lt;/h2&gt;
&lt;p&gt;Devrin just signed up for Twitter. Exciting! He posts a message:
&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Hello, world!
&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Not brilliant, but it&amp;#8217;ll do for an inaugural post. Besides, he has so much to
   tell the world! He&amp;#8217;ll beguile the internet with his 140-character wit and steal
   their hearts! He&amp;#8217;ll have many thousands of followers!
&lt;/p&gt;
&lt;p&gt;Devrin recovers from his unbridled enthusiasm and ventures into Twitter&amp;#8217;s deep
   bowels. &amp;#8220;I must find someone to follow,&amp;#8221; he thinks. And follow he does: the
   first victim is none other than &lt;a href=&quot;http://daringfireball.net&quot; title=&quot;Daring Fireball&quot;&gt;John Gruber&lt;/a&gt;, &lt;a href=&quot;http://43folders.com&quot; title=&quot;43 Folders&quot;&gt;Merlin Mann&lt;/a&gt; follows,
   and &lt;a href=&quot;http://stevenf.com&quot; title=&quot;Steven Frank&quot;&gt;Steven Frank&lt;/a&gt; is felled soon thereafter. Devrin goes to his timeline
   and admires it. His post, alongside the likes of those three! He feels moved to
   post again:
&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;This is super cool!
&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;And quits Twitter forever &amp;#8211; or not. He should have. In reality it took 52
   weeks and a few hundred &amp;#8220;tweets&amp;#8221; before he gathered the intestinal fortitude to
   do it.
&lt;/p&gt;

&lt;h2&gt;Some Background&lt;/h2&gt;
&lt;p&gt;When Twitter was released it garnered naught but harsh words. No one could see
   any merit in a system that restricted you to 140 characters. &amp;#8220;It&amp;#8217;s a waste of
   bandwidth,&amp;#8221; they decided. And moved on.
&lt;/p&gt;
&lt;p&gt;Twitter exploded a little more than a year later. Suddenly bloggers decided
   that Twitter was the Next Big Thing and rang up accounts. Their dutiful
   readerships followed suit, creating accounts for the sole purpose &amp;#8211; as I did
   &amp;#8211; of reading their favorite blogger&amp;#8217;s tweets. And bloggers &lt;em&gt;loved it&lt;/em&gt;: their
   audience at their fingertips! Have a question? No problem! Tweet it and &amp;#8211;
   zing! &amp;#8211; you&amp;#8217;ve got answers!
&lt;/p&gt;
&lt;p&gt;The unexpected explosion melted Twitter&amp;#8217;s servers. And now the Big Thing to
   blog was Twitter&amp;#8217;s unreliability: what kind of self-respecting service has
   hours of downtime? And the slashdot effect increased Twitter&amp;#8217;s problems. And
   users. Today, a bit later, things seem to be running more stably.
&lt;/p&gt;

&lt;h2&gt;Hey You Up There! Twitter Sucks!&lt;/h2&gt;
&lt;p&gt;Why did Twitter&amp;#8217;s first reviewers find so much to hate? They had &lt;em&gt;no audience&lt;/em&gt;.
   Twitter was like writting letters and dropping them on the ground. A little
   while later these same people were back on Twitter lavishing praise because &amp;#8211;
   neat! &amp;#8211; all of sudden there were all these people that &lt;em&gt;wanted&lt;/em&gt; to read this
   crap you threw on the ground! Before 140 characters was an arbitrary
   limitation, now it&amp;#8217;s &amp;#8220;inspired&amp;#8221; and &amp;#8220;revolutionary.&amp;#8221; What the heck changed?
&lt;/p&gt;
&lt;p&gt;The people calling the shots now like Twitter. It&amp;#8217;s this New Medium that
   connects people. In reality it&amp;#8217;s a big rat race for followers and favorited
   tweets. Not for those on the top &amp;#8211; for those on the bottom. The basement of
   Twitter is one big Digg comment thread; it&amp;#8217;s the usual mix of ep1c fa1lz, brb
   bathroom, and OMG! coot puppys! It&amp;#8217;s as if you could create a site that looked
   like Facebook to the guys on top and MySpace to those beneath.
&lt;/p&gt;
&lt;p&gt;The only people that anyone follows &amp;#8211; even the popular users &amp;#8211; are the
   popular users. Strange! This is how Twitter fails: &lt;strong&gt;there&amp;#8217;s no way to discover
users.&lt;/strong&gt; Sure, point me to the search bar. Point me to &amp;#8220;follows&amp;#8221; list on
   everyone&amp;#8217;s page. But there&amp;#8217;s no way for me to find users that talk about the
   same stuff I do. Twitter doesn&amp;#8217;t put me in touch with these people. Twitter
   doesn&amp;#8217;t forge new connections, it only reproduces the blog &amp;amp; audience
   relationship that already exists. That&amp;#8217;s how Twitter fails. That&amp;#8217;s why Twitter
   sucks.
&lt;/p&gt;
&lt;p&gt;Twitter is your high school lunchroom where the uncool kids are too busy
   peering over each other to get a glimpse of the cool table to even notice each
   other.
&lt;/p&gt;

&lt;h2&gt;One Year Later&lt;/h2&gt;
&lt;p&gt;And so a year later, thoroughly disillusioned, I pull the plug. Some will read
   this and agree.
&lt;/p&gt;
&lt;p&gt;But the vast majority will &amp;#8211; I feel &amp;#8211; think, &amp;#8220;You dolt. You can&amp;#8217;t say &lt;em&gt;you&lt;/em&gt;
   don&amp;#8217;t like Twitter and because of that Twitter as a whole sucks.&amp;#8221; Point taken.
   Maybe there are those that actually have friends on Twitter &amp;#8211; how&amp;#8217;d you swing
   that? &amp;#8211; or those that use it because they enjoy reading tweets from those on
   high. Fair enough. But to the latter: that&amp;#8217;s not what Twitter is for. They
   provide RSS feeds if that&amp;#8217;s all you want.
&lt;/p&gt;
&lt;p&gt;Too many people join Twitter because they hear that it&amp;#8217;s awesome. This is to
   you: don&amp;#8217;t. It&amp;#8217;s not.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/i_hate_twitter_and_yes_thank_you_i_did_take_my_pills_this_morning.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/is_a_filesystem-based_blog_right_for_you.html</id><title>Is a Filesystem-Based Blog Right for You?</title><updated>2008-07-29T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;&lt;a href=&quot;http://cdleary.tumblr.com/post/37562612/why-file-as-blog-entry-blog-engines-have-problems&quot;&gt;Chris&lt;/a&gt; pointed me to an insightful post by &lt;a href=&quot;http://utcc.utoronto.ca/~cks/space/blog/web/EntryAsFileProblems&quot;&gt;Chris Siebenmann&lt;/a&gt; on the
   shortcomings of filesystem-based blogs. I&amp;#8217;ll summarize his points:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;p&gt;Editing a post changes the modification time; this gets annoying when all you
     want to do is fix a typo and not republish.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Embedding metadata is akward.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Storing metadata in a static location defeats the entire purpose of
     abandoning a database-driven engine.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best defense I can come up with is something like this: if you&amp;#8217;re having
   these problems with your file-based blog, you probably shouldn&amp;#8217;t be using one.
   I don&amp;#8217;t think file-based blogs are superior to anything driven by a database;
   in fact they&amp;#8217;re pretty much dumber overall. If you need the metadata that
   database-driven blogs provide you&amp;#8217;re probably better off just using one rather
   than trying to turn a file-based blog into something that it&amp;#8217;s not.
&lt;/p&gt;
&lt;p&gt;I think file-based blogs shine when your blog can be better described as a
   loose coupling of essays. I make no claims that my posts are worthy of being
   labeled as such, but they are infrequent and permanent. My &lt;a href=&quot;http://aneviltrend.tumblr.com/&quot;&gt;tumblr&lt;/a&gt; page is
   what I reserve for musings and link-posting; this site is meant for posts that
   I&amp;#8217;d like everyone to be able to see for a while.
&lt;/p&gt;
&lt;p&gt;Nevertheless, I do believe there are a few simple tricks that you can pull to
   adequately address some of Siebenmann&amp;#8217;s points.
&lt;/p&gt;

&lt;h2&gt;Modification Times&lt;/h2&gt;
&lt;p&gt;The solution I have is to include the post date along with the title at the top
   of my posts. The first two lines of this post are:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Is a Filesystem-Based Blog Right for You?
6/8/2008
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;http;//launchpad.net/can/&quot;&gt;Can&lt;/a&gt; interprets the first line as the title &amp;#8211; and formats a slug
   accordingly &amp;#8211; and the second line as the publication date. The post gets
   published at noon of the day given and isn&amp;#8217;t published if the date is in the
   future. The modification time of the file has nothing to do with the
   publication time.
&lt;/p&gt;
&lt;p&gt;Reminds me of how we used to title our homework assignments in grade
   school.
&lt;/p&gt;

&lt;h2&gt;Metadata&lt;/h2&gt;
&lt;p&gt;Siebenmann is concerned about a lot more than publication times: metadata can
   include tags, categories, revisions, modification times, and so on. I don&amp;#8217;t
   think file-based blogs are cut out to handle gobs of metadata; if you find
   yourself needing that data it&amp;#8217;s probably time to move to something like
   &lt;a href=&quot;http://wordpress.org&quot;&gt;Wordpress&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;I feel that Siebenmann&amp;#8217;s last point &amp;#8211; that having local storage for metadata
   &amp;#8211; is addressed by what I just said above.
&lt;/p&gt;

&lt;h2&gt;Bonus Problem: Post-specific Media&lt;/h2&gt;
&lt;p&gt;File-based engines have no real way to store media in connection with a post. I
   considered a few options:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;Just don&amp;#8217;t. Have a &lt;code&gt;/media&lt;/code&gt; directory and hard-code in links in posts.
   Can&amp;#8217;t name two pieces of media the same thing (i.e. no &lt;code&gt;foo.jpg&lt;/code&gt; in two
   posts).
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Turn each post into a folder with the post text file and any associated
   media files inside. Just one problem: it&amp;#8217;s a real pain in the butt. Kind of
   defeats the purpose of being able to just drop posts into a directory and
   publish them.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Create a folder for each post in a &lt;code&gt;/media&lt;/code&gt; directory and have can
   modify links in the post to point at this new location. I&amp;#8217;ll explain this
   one below.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Embrace the possibility of a blog without any media. Would do that, but I
   already have posts with screenshots and such.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My initial post on can outlined what I was planning: basically to search
   and replace links in the post source. To quote myself:
&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;But I the approach I&amp;#8217;d like is something like this:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Publishing script creates a directory per post in a specified media base
       directory.
 &lt;/li&gt;

 &lt;li&gt;
     Drop any media corresponding to a particular post into said directory.
 &lt;/li&gt;

 &lt;li&gt;
     The post source uses a flag &amp;#8211; something like &lt;code&gt;class='media'&lt;/code&gt; &amp;#8211; in links
  that reference local media. The publishing script looks for these in posts
  and prepends the post&amp;#8217;s media directory to the link.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;&lt;p&gt;The first two are right. The third point is crap. What I want is simplicity:
   can uses Markdown, and including a class for a link means writing out the
   link by hand. The solution I use is to just have links that look like:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a href='/media/foo.jpg'&amp;gt;...&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Simple. During publishing can goes through and replaces that link with
   this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;a href='/media/post_slug/foo.jpg'&amp;gt;...&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And I drop &lt;code&gt;foo.jpg&lt;/code&gt; into that folder to complete the process. Lets me use
   identical names and, more importantly, it keeps the media folder nice and
   organized. Still not as easy as database-based blogs, but thankfully I&amp;#8217;m
   text-heavy and tend not to have any media.
&lt;/p&gt;
&lt;p&gt;(Disclaimer: can actually doesn&amp;#8217;t do any of this. But it will. Soon.)
&lt;/p&gt;

&lt;h2&gt;Pick Your Poison&lt;/h2&gt;
&lt;p&gt;File-based blogs aren&amp;#8217;t popular. For many they&amp;#8217;re going to be a square peg in a
   round hole.  But if your blog isn&amp;#8217;t complicated or updated often then they
   offer a simplicity that something like Wordpress can&amp;#8217;t.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/is_a_filesystem-based_blog_right_for_you.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/can.html</id><title>Can</title><updated>2008-05-15T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;Can is the blogging engine I&amp;#8217;ve rolled for my site, with a generous tip &amp;#8216;o the hat to &lt;a href=&quot;http://stevenf.com/archive/laguna.php&quot;&gt;Steven Frank&lt;/a&gt;. It&amp;#8217;s almost unfair to call this an &amp;#8220;engine&amp;#8221;: really it&amp;#8217;s just 100 lines of Python (and not very good Python, either). Whether that&amp;#8217;s an indication of Python&amp;#8217;s awesomeness or just my laziness I&amp;#8217;ll leave to you. Either way it does what I need it to do:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Blog posts are just text files I&amp;#8217;ve saved in a directory.
 &lt;/li&gt;

 &lt;li&gt;
     I use &lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt; as input.
 &lt;/li&gt;

 &lt;li&gt;
     Running &lt;code&gt;python can.py publish&lt;/code&gt; spits out my entire blog in HTML files. No server-side processing.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;#8217;s far from where I want it to be. The templating system sucks. There&amp;#8217;s no good way of saving media for posts. &lt;del&gt;It doesn&amp;#8217;t spit out an RSS feed&lt;/del&gt;. But it has one thing going for it: it&amp;#8217;s &lt;a href=&quot;https://launchpad.net/can/&quot;&gt;on Launchpad.net&lt;/a&gt;. Branch it, add junk, and merge it back in. Or don&amp;#8217;t.
&lt;/p&gt;
&lt;p&gt;This means that I&amp;#8217;ve (again) broken all URLs to my site. I&amp;#8217;ve noticed that &amp;#8211; because I hardly write &lt;em&gt;anything&lt;/em&gt; &amp;#8211; I can remove (almost) all unecessary cruft in the URLs. Before and after:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://aneviltrend.com/blog/articles/2008/05/06/can

http://aneviltrend.com/archive/can.html
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I&amp;#8217;m still slapping myself for that &lt;code&gt;/blog/articles&lt;/code&gt; bit of the URL. Tim Berners-Lee, the guy who coded the first internet browser, penned an excellent article on the art of &lt;a href=&quot;http://www.w3.org/Provider/Style/URI&quot;&gt;beautiful URLs&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Where do I see can going from this point forward? The templating system needs an overhaul. I have three template files describing a base page layout with about one line of difference between each, in flagrant violation of &lt;acronym title=&quot;Don't Repeat Yoursef&quot;&gt;DRY&lt;/acronym&gt; principles. The backend for the templates is hack as well: searching for known strings and using &lt;code&gt;re.sub()&lt;/code&gt; to insert HTML. I feel that a cleaner approach would use Python&amp;#8217;s built-in &lt;acronym title=&quot;Document Object Model&quot;&gt;DOM&lt;/acronym&gt; support.
&lt;/p&gt;
&lt;p&gt;Media support just doesn&amp;#8217;t exist. At this point my old posts with screenshots are pulling graphics from a temporary directory I set up. But I the approach I&amp;#8217;d like is something like this:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Publishing script creates a directory per post in a specified media base directory.
 &lt;/li&gt;

 &lt;li&gt;
     Drop any media corresponding to a particular post into said directory.
 &lt;/li&gt;

 &lt;li&gt;
     The post source uses a flag &amp;#8211; something like &lt;code&gt;class='media'&lt;/code&gt; &amp;#8211; in links that reference local media. The publishing script looks for these in posts and prepends the post&amp;#8217;s media directory to the link.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It seems a bit excessive &amp;#8211; why not just hard code in the link? &amp;#8211; but this approach seems to be the cleanest from a &amp;#8220;writing the post&amp;#8221; view: I don&amp;#8217;t need to worry about what the generated slug will be (since that will likely be the name of the media directory) and it&amp;#8217;s clean markup.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/can.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/web_presence.html</id><title>Web Presence</title><updated>2008-03-01T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;I&amp;#8217;ve been signing up for an alarming amount of web apps lately. Nearly every
   site that I visit asks me to put down my name before it&amp;#8217;ll let me in. And,
   sucker that I am, I tend to use my &lt;a href=&quot;http://www.penny-arcade.com/comic/2006/10/26&quot;&gt;real name&lt;/a&gt;. 
&lt;/p&gt;

&lt;h2&gt;spreading thin&lt;/h2&gt;
&lt;p&gt;Where am I on the net?
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     AIM
 &lt;/li&gt;

 &lt;li&gt;
     This site
 &lt;/li&gt;

 &lt;li&gt;
     Tumblr
 &lt;/li&gt;

 &lt;li&gt;
     Twitter
 &lt;/li&gt;

 &lt;li&gt;
     Google mail, docs, groups, etc.
 &lt;/li&gt;

 &lt;li&gt;
     Blogspot
 &lt;/li&gt;

 &lt;li&gt;
     Facebook
 &lt;/li&gt;

 &lt;li&gt;
     Last.fm, Pandora
 &lt;/li&gt;

 &lt;li&gt;
     Slashdot
 &lt;/li&gt;

 &lt;li&gt;
     Plan 9 &amp;amp; gEDA mailing lists
 &lt;/li&gt;

 &lt;li&gt;
     deviantART
 &lt;/li&gt;

 &lt;li&gt;
     Parallax: &lt;a href=&quot;http://www.parallax.com/tabid/322/Default.aspx&quot;&gt;mobile desk chair project&lt;/a&gt;
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quite a list. I&amp;#8217;m making no claims here though: you may have more or less. The
   point is, though, that our every move on the web is captured. If I post to the
   Plan 9 mailing list my &lt;a href=&quot;http://www.google.com/search?hl=en&amp;amp;q=devrin+talen&amp;amp;btnG=Google+Search&quot;&gt;Google&lt;/a&gt; will list that post as my top search result.
   What if that post was a nasty reply? What if it was just plain stupid? That post
   is archived by hundreds of sites. It&amp;#8217;s not getting lost.
&lt;/p&gt;

&lt;h2&gt;being careful&lt;/h2&gt;
&lt;p&gt;Granted it&amp;#8217;s easy to simply &lt;em&gt;not care&lt;/em&gt;. So what if a Google search of my name
   turns up someone who &lt;a href=&quot;http://www.penny-arcade.com/comic/2004/03/19&quot;&gt;trolls forums&lt;/a&gt; and pesters mailing lists?  The
   easy answer: that it really doesn&amp;#8217;t matter. How many people search for me
   online? How many would, if they saw those posts, even know me? Will these sites
   even be around ten years down the road?
&lt;/p&gt;
&lt;p&gt;And if you don&amp;#8217;t use your real name then that answer might suffice. The
   anonymity of the internet makes it easy to be multiple people. But I&amp;#8217;d like to
   focus on those that are trying to cultivate a presence. Just like the &amp;#8220;real
   world&amp;#8221; your name on the internet carries weight. It carries your image. And with
   how prominent the internet has become it&amp;#8217;s beginning to carry a significant
   amount of your identity.
&lt;/p&gt;
&lt;p&gt;I believe that we take these online personas for granted. With every 
   web app that gets released we have another opportunity to create yet another
   identity. Unlike our analog counterpart that forgets and is forgotten, the web
   identity you create is permanent. The internet, cruel mistress that she is, will
   never lose that terrifically embarrassing photo. Or video. Or &lt;a href=&quot;http://bash.org/?201579&quot;&gt;post&lt;/a&gt;.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/web_presence.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/a_cursory_look_at_makefiles.html</id><title>A Cursory Look at Makefiles</title><updated>2008-02-12T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;New to Makefiles? At best they&amp;#8217;re confusing, and at worst completely
   incomprehensible. Here&amp;#8217;s a dissection of a &lt;em&gt;simple&lt;/em&gt; Makefile.
&lt;/p&gt;

&lt;h2&gt;structure&lt;/h2&gt;
&lt;p&gt;The basic format of a Makefile follows this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;targets&amp;gt; : &amp;lt;dependencies&amp;gt;
    &amp;lt;commands&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Where multiple entries will make up a larger Makefile. A simple Makefile to
   compile a &lt;code&gt;helloworld.c&lt;/code&gt; program might look something like this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;helloworld.o : helloworld.c
    gcc -o helloworld.o helloworld.c
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The target is &lt;code&gt;helloworld.o&lt;/code&gt;, and it depends on having &lt;code&gt;helloworld.c&lt;/code&gt;. Running
   the following command:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ make helloworld.o
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Will cause &lt;code&gt;gcc&lt;/code&gt; to be run as specified in the Makefile.
&lt;/p&gt;

&lt;h2&gt;practical makefiles&lt;/h2&gt;
&lt;p&gt;Developing a Makefile that might actually be used in a smallish software project
   involves a bit more work. Generally speaking, the project will consist of
   several &amp;#8211; in this case &amp;#8211; .c files, which will need to be linked in
   interesting ways against each other.
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;%&lt;/code&gt;, &lt;code&gt;$@&lt;/code&gt;, and &lt;code&gt;$^&lt;/code&gt; are all special variables. Here&amp;#8217;s how they might be used:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%.o : %.c
    gcc -o $@ $^
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;%&lt;/code&gt; grabs the matching string from the target and applies it to the
   dependency. If the target is &lt;code&gt;foo.h&lt;/code&gt;, the Makefile will search for &lt;code&gt;foo.c&lt;/code&gt;. The
   next variable, &lt;code&gt;$@&lt;/code&gt;, grabs whatever file matched the target. Likewise, &lt;code&gt;%^&lt;/code&gt;
   grabs the file(s) that matched the dependency.
&lt;/p&gt;
&lt;p&gt;Thus running
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ make helloworld.o
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will, as above, run &lt;code&gt;gcc -o helloworld.o helloworld.c&lt;/code&gt;. The &lt;code&gt;%&lt;/code&gt; operator will
   match &amp;#8220;helloworld&amp;#8221;, the &lt;code&gt;$@&lt;/code&gt; grabs &lt;code&gt;helloworld.o&lt;/code&gt;, and the &lt;code&gt;$^&lt;/code&gt; grabs
   &lt;code&gt;helloworld.c&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;Most Makefiles will also define some standard targets, such as &lt;code&gt;clean&lt;/code&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;clean :
    rm -f *.o
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That covers the basics. For additional resources on Makefiles check out:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     The &lt;a href=&quot;http://www.gnu.org/software/make/manual/make.html&quot;&gt;GNU make page&lt;/a&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;a href=&quot;http://www.gnu.org/software/make/&quot;&gt;GNU make overview&lt;/a&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     The &lt;a href=&quot;http://en.wikipedia.org/wiki/Make_(software)&quot;&gt;Wikipedia entry&lt;/a&gt;.
 &lt;/li&gt;
&lt;/ul&gt;</content><link href="http://aneviltrend.com/archive/a_cursory_look_at_makefiles.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/a_variation_on_mips.html</id><title>a variation on mips</title><updated>2008-01-14T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;h2&gt;Parallel ISA (PISA) Overview&lt;/h2&gt;
&lt;p&gt;Uses PC-indirect addressing to specify &amp;#8216;registers.&amp;#8217; Meant to easily enable
   out-of-order execution and multiple-issue logic in hardware. Otherwise exactly
   like MIPS. Pronounced as &amp;#8220;pizza.&amp;#8221;
&lt;/p&gt;
&lt;p&gt;The modifications are to the source and destination registers. Source registers
   are not addressed directly, but rather by providing the PC offset to the
   instruction whose result will be used. The destination register field is
   removed.
&lt;/p&gt;
&lt;p&gt;Example:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addiu   $0, 5   ; x = 5
addiu   $0, 4   ; y = 4
add     -1, -2  ; adds x + y
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hardware can now easily determine that the first two loads can happen in
   parallel &amp;#8211; or out of order &amp;#8211; but that the addition depends on the results of
   the loads. The add cannot be issued until both loads complete. Essentially, the
   ISA makes dependencies between instructions very clear.
&lt;/p&gt;

&lt;h2&gt;Register File&lt;/h2&gt;
&lt;p&gt;Essentially a &amp;#8220;cache&amp;#8221; of registers. Because each entry needs to keep track of
   the PC of the instruction that wrote it, the register file needs to keep a tag
   record for each entry. This will incur a much higher hardware overhead in the
   register file. A direct-mapped approach is used to reduce this penalty.
&lt;/p&gt;
&lt;p&gt;To support parallel operation two additional bits are needed for each entry:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Valid bit: because the register file is now essentially a cache, a valid bit
     is needed for each entry to ensure that it is valid data.
 &lt;/li&gt;

 &lt;li&gt;
     Pending bit: when an instruction is issued the destination register entry
     will have the pending bit set high. Any instruction down the line that
     depends on this register entry will be stalled until the pending bit is
     lowered again.
 &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Non-sequential code&lt;/h2&gt;
&lt;p&gt;This approach works well for sequential code, but begins to break down when
   loops and branches are used. Take this example:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addiu   $0, 1
addiu   $0, 5       ; x = 5

loop:
blez    -1, done    ; if( x==0 ) goto done
subi    -2, -3      ; x = x-1
j       loop

done:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;blez&lt;/code&gt; branch, because it only checks the result of the &lt;code&gt;ldi 0x05&lt;/code&gt;
   instruction, will never be taken. The &lt;code&gt;subi&lt;/code&gt; instruction stores its result at a
   +1 offset to the &lt;code&gt;blez&lt;/code&gt;, which the branch does not check.
&lt;/p&gt;
&lt;p&gt;This issue gives us the following addition to the instruction set. The &lt;code&gt;rd&lt;/code&gt;
   field of the MIPS ISA, previously unused in this implementation, will now be
   used to store an optional destination entry in the register file. The above
   example can be rewritten as:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addiu   $0, 1
addiu   $0, 5, +2   ; x = 5, store into PC+2

loop:
blez    +1, done    ; if( x==0 ) goto done
subi    0, -3       ; x = x-1
j       loop

done:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The compiler should assign the branch condition to inspect the result of the
   last instruction within the loop to assign to the register in question. The last
   instruction &lt;em&gt;before&lt;/em&gt; the branch evaluation should be compiled to be written to
   the same PC as the former instruction.
&lt;/p&gt;
&lt;p&gt;How does this affect the parallel operation of the processor? It should have no
   effect on the operation and should require minimal additional hardware.
   Previously, without the destination register field, instructions were
   essentially writing to offset &lt;code&gt;0&lt;/code&gt;. All that has changed is that instructions can
   now write to other offsets. The valid and pending bits will still ensure correct
   parallel operation of superscalar implementations.
&lt;/p&gt;
&lt;p&gt;This approach has the disadvantage of being taxing on compilers. Whether this
   proves to be a major issue or not will need to be seen.
&lt;/p&gt;

&lt;h2&gt;Disadvantages&lt;/h2&gt;
&lt;p&gt;This approach suffers from another disadvantage: the inability to reference the
   result of an instruction that is at a greater offset than &lt;code&gt;N&lt;/code&gt;, where &lt;code&gt;N&lt;/code&gt; is the
   register file size. Because the register file uses the PC of an instruction to
   store entries, an instruction more than an offset of &lt;code&gt;N&lt;/code&gt; away from another
   cannot use the result of the latter. This is an inherent limitation of the
   instruction set.
&lt;/p&gt;
&lt;p&gt;A workaround is to write a value that must be accessed later to memory. This
   might lead to an increased number of memory accesses throughout the program,
   which will lead to decreased performance.
&lt;/p&gt;
&lt;p&gt;Another simple solution is to simply increase the size of the register file.
   Though this would lead to increased hardware costs and might lead to longer
   delays in register file reads, this would solve the problem somewhat.
&lt;/p&gt;
&lt;p&gt;Interestingly, the problem could also be alleviated by adding a second layer
   register file cache, much like adding a second layer data cache. This would
   offer the benefits of making register entries available for longer periods, but
   has the disadvantage of making program flow harder to predict. A compiler would
   need to keep track of the simulated cache state to determine if a register entry
   will still be available at a later point in the program.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/a_variation_on_mips.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/the_assembler.html</id><title>The Assembler</title><updated>2008-01-07T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;My friend &lt;a href=&quot;http://cdleary.blogspot.com/&quot;&gt;Chris&lt;/a&gt; and I recently finished our &lt;a href=&quot;http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2007/blh36_cdl28_dct23/blh36_cdl28_dct23/index.html&quot;&gt;USB project&lt;/a&gt;. I was trying
   to think of a good way to present this in a post, and decided to highlight one
   small part of the project: the assembly that drives the lowest layers of the
   software stack.
&lt;/p&gt;

&lt;h2&gt;Old School&lt;/h2&gt;
&lt;p&gt;Last semester I had hacked up the assembly for our project without much
   foresight or care for elegance. We were more preoccupied with trying to grasp
   the &lt;a href=&quot;http://www.usb.org/developers/docs/&quot;&gt;650-page spec&lt;/a&gt; that is USB, and beautiful code was the least of our
   worries.
&lt;/p&gt;
&lt;p&gt;Though the code didn&amp;#8217;t &lt;em&gt;look&lt;/em&gt; good, it still had to &lt;em&gt;be&lt;/em&gt; good, and here&amp;#8217;s what
   it had to accomplish:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Output one bit from a buffer in memory every 10 cycles (no more, no less).
 &lt;/li&gt;

 &lt;li&gt;
     Keep track of the number of bits sent and stop when that is equal to a given
     bit count.
 &lt;/li&gt;

 &lt;li&gt;
     Every eight bits sent load another byte from memory.
 &lt;/li&gt;

 &lt;li&gt;
     Raise and lower the enable line so that the Mega32 can drive the bus when
     transmitting and read the bus when receiving.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This becomes a tall task when you only have 9 cycles to work with (one cycle is
   needed to output on the I/O pins). Let&amp;#8217;s look at what the assembly I wrote last
   semester for transmitting a packet looks like:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#define SIE_TOKEN_BIT
    mov r20, r3
    andi r20,0x01
    add r20, r10
    out %1, r20
    lsr r3
    subi r16, 1
    brne .+4
    jmp .sie_send_token_eop

/* Token: Send bit, and nop until next one */
#define SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT
    NOP2

/* Token: Send bit, and buffer another byte */
#define SIE_TOKEN_BIT_BUFFER
    SIE_TOKEN_BIT
    ld r3, X+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first thing to note is that &lt;em&gt;all loops were unrolled&lt;/em&gt; in this assembly. To
   send a byte, we had this macro:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#define SIE_TOKEN_BYTE
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_NOP
    SIE_TOKEN_BIT_BUFFER
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This would literally copy and paste in the assembly above about eight times. And
   that wasn&amp;#8217;t even the worst of it: because the loops were unrolled, we had to
   copy in enough loop iterations for the worst case scenario. For the data packet
   transmit code &amp;#8211; which at most could send 103 bits &amp;#8211; we had the byte macro
   copied in 13 times. This equated to about &lt;em&gt;936 lines of code&lt;/em&gt; &amp;#8211; for just one
   small part of the SIE code. The sheer size of this hurt us; our code weighed in
   at about 20 KB when compiled. On a device with only 32 KB of program flash
   memory this becomes a bit of a problem (considering that our code was intended
   as a companion library to an existing user program).
&lt;/p&gt;
&lt;p&gt;The assembly above shouldn&amp;#8217;t be too confusing, but a few notes are in order.
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     &lt;code&gt;r3&lt;/code&gt; is used to store the byte buffered from memory.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;r20&lt;/code&gt; is used as a temporary register.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;r10&lt;/code&gt; holds the value &lt;code&gt;0x05&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;%1&lt;/code&gt; is a compiler directive for &lt;code&gt;PORTA&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;r16&lt;/code&gt; holds the bit count for the given packet.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of the lines are explained in order:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;&lt;code&gt;mov r20, r3&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;Copies the buffer register into the temporary register.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;andi r20,0x01&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;Performs an AND operation on the temporary register with a bit mask to
   extract the lowest bit. This is the bit that will be sent on the bus.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;add r20, r10&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;Adds the bit to be sent with 5: what this is essentially doing is
   differentially encoding the signal and setting the enable pin high at the
   same time. The pin assignments were: enable on pin 2, D+ on pin 1, and D- on
   pin 0. Thus if the bit in the temporary register is 1, meaning that we
   should be sending a differential 1, adding 5 will yield &lt;code&gt;0b00000110&lt;/code&gt;. The
   enable line is set high, as is D+. D- is low.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;out %1, r20&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;Outputs the value of the temporary register on &lt;code&gt;PORTA&lt;/code&gt;.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;lsr r3&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;Shifts the buffer register down one, getting it ready for when the next bit
   will be sent.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;subi r16, 1&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;Decrements the bit count by one.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;brne .+4&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;When the bit count hits zero, this branch will not be taken.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;code&gt;jmp .sie_send_token_eop&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;If the above branch is not taken &amp;#8211; meaning that all bits have been sent
   &amp;#8211; then the code will jump to the end-of-packet handler.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Repeat this seven times, and add a load instruction on the eighth, and you have
   the complete workings of last semester&amp;#8217;s assembly. It worked, true, but it was
   gross; and with an entire semester to rework stuff I decided to sit down and
   hammer out some nice code.
&lt;/p&gt;

&lt;h2&gt;New School&lt;/h2&gt;
&lt;p&gt;We came into this semester knowing that USB with a Mega32 is indeed possible.
   We also knew what USB &lt;em&gt;was&lt;/em&gt;. We figured that a full code overhaul would be in
   order, and there&amp;#8217;s no better place to start than at the bottom.
&lt;/p&gt;
&lt;p&gt;The assembly, from above, was completely tossed. Little by little we came up
   with our new assembly &amp;#8211; replete with rolled-up loops and clever hacks.  These
   changes required some small modifications to the hardware, but nothing major.
&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the code that made it into our final revision:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#define TX_PACKET(label,mem_pointer,bit_count_reg)
    mov     r5, __zero_reg__
    ldi     r20, 0x01

    /* buffer */
    .sie_#label_tx_buffer:
    ld      r10, #mem_pointer+

    /* bit tx */
    .sie_#label_tx_bit:
    lsl     r10
    rol     r20
    out     %4, r20

    /* completion checks */
    dec     #bit_count_reg
    breq    .sie_#label_tx_done

    add     r5, r3
    brcs    .sie_#label_tx_buffer

    ldi     r20, 0x01
    rjmp    .sie_#label_tx_bit

    /* done */
    .sie_#label_tx_done:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I could try to explain all the assembly here, but I&amp;#8217;d be repeating an entire
   chapter of our documentation on the project. Chapter 4 of &lt;a href=&quot;/images/usb_documentation.pdf&quot;&gt;the documentation&lt;/a&gt;
   covers each line of the assembly and how it works. Check it out, or try and
   figure out what the assembly is doing on your own. Should you choose to do that,
   know that:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     The pin assignments are: enable on pins 1 &amp;amp; 2 (these get ORed together into
     one enable line) and transmit on pin 0 (this gets differentially encoded by
     the hardware).
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;%4&lt;/code&gt; is a compiler directive for the USB port.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;#label&lt;/code&gt;, &lt;code&gt;#mem_pointer&lt;/code&gt;, and &lt;code&gt;#label&lt;/code&gt; are parameters passed to the macro
and are pasted into the macro where needed before the code is compiled.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;code&gt;r3&lt;/code&gt; holds the value &lt;code&gt;0x20&lt;/code&gt;.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Explanation aside, the punchline is that nearly 1000 lines of assembly in our
   previous project got replaced with just &lt;em&gt;12&lt;/em&gt; lines of cleverness.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/the_assembler.html" rel="alternate"/></entry><entry><id>http://aneviltrend.com/archive/everyday_linux:_rsync.html</id><title>Everyday Linux: rsync</title><updated>2007-11-05T12:00:00-05:00</updated><author><name>Devrin Talen</name></author><content type="html">&lt;p&gt;I have two computers, both of which I like to listen to music on: my laptop, for
   when I&amp;#8217;m in class (ahem, &lt;em&gt;studying&lt;/em&gt;), and my desktop when I&amp;#8217;m in my room. I
   use iTunes on my laptop and Amarok on my desktop. You can see that I might have a few
   issues when syncing my music between the two computers. How I do it is today&amp;#8217;s 
   Everyday Linux.
&lt;/p&gt;

&lt;h2&gt;rsync&lt;/h2&gt;
&lt;p&gt;This is my typical scenario: I&amp;#8217;m on campus, and I&amp;#8217;ve just got some music from a
   site like &lt;a href=&quot;http://soul-sides.com/&quot;&gt;soul sides&lt;/a&gt; or Amazon&amp;#8217;s sweet new &lt;a href=&quot;http://www.amazon.com/MP3-Music-Download/b?ie=UTF8&amp;amp;node=163856011&quot;&gt;music store&lt;/a&gt;. I import my 
   music and listen to it on iTunes. Later I get back to my room, and would like to 
   listen to my new music with the better speakers hooked up to my desktop. How do
   I sync up my music?
&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m never typically near nor have access to my
   desktop whenever I get new music. So I need a way to copy whatever music I have
   over to my desktop. But why not just copy over the music manually? Well, I
   &lt;em&gt;could&lt;/em&gt;, but that&amp;#8217;s not the cool way to do it.
&lt;/p&gt;
&lt;p&gt;The more practical reason is that iTunes on my laptop organizes my music as it
   sees fit, and I&amp;#8217;d rather not have to traverse arcane directory names in order to
   get to the folder that I want to copy over. Amarok, fortunately, is much more
   forgiving with its organization, and will put up with the structure that iTunes
   uses. I also prune my music collection from time to time, and would rather not
   have to track what changes I make to do the same on my desktop. In short: I need
   rsync so I have a drop-dead simple syncing system for my music.
&lt;/p&gt;
&lt;p&gt;rsync is a utility that synchronizes files and directories. They can be two
   local directories, two remote, one local and one remote, it doesn&amp;#8217;t matter. All
   it takes is one terminal command (given, you&amp;#8217;ll probably spend some time
   perfecting this command). The other caveat is that (if you&amp;#8217;re using
   rsync with remote computers) you&amp;#8217;ll need to set up the rsync daemon on any
   remote computers you connect to.
&lt;/p&gt;

&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The first step was to get my desktop set up for rsync. I created a music folder
   in my home directory to begin, then set up the &lt;code&gt;rsyncd.conf&lt;/code&gt; file in my &lt;code&gt;/etc&lt;/code&gt;
   directory.
&lt;/p&gt;
&lt;p&gt;To set up rsync on my Ubuntu system I followed along at the &lt;a href=&quot;http://ubuntuguide.org/wiki/Ubuntu:Feisty#How_to_copy_files.2Ffolders_from_local_machine_into_a_remote_Ubuntu_host_.28rsync.29&quot;&gt;ubuntu guide
entry&lt;/a&gt; and at another &lt;a href=&quot;http://everythinglinux.org/rsync/&quot;&gt;excellent page&lt;/a&gt;. Here are some of the highlights:
&lt;/p&gt;
&lt;p&gt;The more exciting parts of this file look like this on my system:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[musicbackup]

path = &amp;lt;home&amp;gt;/music
comment = the music backup location
secrets file = /etc/rsyncd.secrets
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Not bad at all. The &lt;code&gt;rsyncd.secrets&lt;/code&gt; file is next:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For me it&amp;#8217;s just one line: my name and password. 
&lt;/p&gt;
&lt;p&gt;Now the fun part is on my laptop. This is the rsync command that I use to do a
   one-way sync from my laptop to my desktop.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rsync --verbose --progress --stats --compress --rsh=/usr/bin/ssh \
    --recursive --times --delete \
    --exclude &quot;Apple&quot; \
    --exclude &quot;Movies&quot; \
    ...
    --exclude &quot;Video&quot; \
    &amp;lt;home&amp;gt;/Music/iTunes/iTunes\ Music/* \
    devrin@&amp;lt;desktop ip&amp;gt;:music
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The options I specify include:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Keep me updated with &lt;code&gt;--verbose&lt;/code&gt; and &lt;code&gt;--progress&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     Minimize the bandwidth with &lt;code&gt;--compress&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     Prune out removed directories with &lt;code&gt;--delete&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     Traverse into each folder with &lt;code&gt;--recursive&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     Don&amp;#8217;t copy a few specific directories (in my case because they have video
     files) by using &lt;code&gt;--exclude&lt;/code&gt;.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It would be a real pain to have to
   type out this entire command each time I wanted to sync, so I copied it into its
   own bash script that I called &lt;code&gt;music_backup.sh&lt;/code&gt;. Now each time I want to back up
   I just invoke my little script:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ./music_backup.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And my music gets synced up. Not bad! You&amp;#8217;ll want to read up on the
   documentation I linked to above to get a better feel for how to use rsync to
   accomplish your goals. There&amp;#8217;s a few steps there that I didn&amp;#8217;t cover but that
   should be fairly trivial to do.
&lt;/p&gt;
&lt;p&gt;All in all, rsync is a great system. It works perfectly for what I need it to
   do, and I&amp;#8217;m sure that a lot of people have some sort of syncing problem that
   could be solved elegantly with rsync.
&lt;/p&gt;</content><link href="http://aneviltrend.com/archive/everyday_linux:_rsync.html" rel="alternate"/></entry></feed>