An Ode to the Cruxen

This is the story of a short time, a quarter century ago, when a little cluster of computers at Cornell University played a very important part in in my life and in the lives of my friends.

It was the fall of 1992, and the Internet was growing up. It would still be another year or two before it became a household name, so for the time being it was our little playground, our special place that you couldn’t get to unless you were at a big research company or a reasonably well endowed University. I lived at Mary Donlon Hall, one of two dorm buildings that had recently been wired with Ethernet and therefore offered its residents a mainline into the addictive world of the Internet.

I remember vividly an evening in September or October of that year, when a friend of mine said “I just got an account on the UNIX machines!”

“What’s UNIX?,” I asked naively. I was a computer enthusiast, but hardly a wizard. Back then I had a hand-me-down IBM XT running IBM DOS 3.3, and although I was familiar with Commodore Amigas and the newfangled Windows operating system that had recently come out, my knowledge didn’t extend far beyond personal computers.

I don’t remember exactly how my friend explained UNIX to me, but I remember the gist: It was a serious operating system, for serious computers. It let many people use the same computer at the same time. Plus, it was way better at the Internet than any little toy PC computer could ever be.

I was kind of awestruck by the idea, and decided right then and there that I needed an account, too. A few days later I marched down to the Cornell Information Technologies office and filled out Xeroxed form promising that I would use the system wisely and follow all the rules, and I was given my own login.

I never actually saw the computers in question. They were locked up in an office somewhere, presumably in the CIT building, but I remember the specs pretty well. There were three of them that first year (though two more would be added in later years):,, and, all DECstation workstations running the ULTRIX operating system, a commercial UNIX developed by DEC. We affectionately called them The Cruxen. They were RISC machines, with MIPS R3000 CPUs and something like 32 MB of RAM each. They were all linked together with NFS and NIS, so you could log into any of them and get access to your home directory regardless of the machine you were using. I don’t remember exactly how much disk space they had, but I want to say all together it added up to 2GB, which was huge at the time.

At first, I didn’t really know what to do with my login. I poked around and learned enough UNIX commands to be pretty dangerous. But then I grew accustomed to using utilities like nn to read Usenet, and mh to read my email, and I started logging in more and more frequently. UNIX was a nice break from the archaic and crash-prone tools I was using in DOS to access the Internet.

It was probably in the spring of 1993 that the Cruxen became a real hang-out spot. Increasingly, I’d notice my friends logged in, and shoot them quick emails out of the blue. Then someone showed me that you could use a tool called msg to send a quick message to someone’s terminal, and if you were interested in more direct communication, you could use talk link your terminals together and chat in real-time. Plus, of course, you could use irc to reach the global IRC network, and telnet to connect to any other system you wanted, including multiuser games called MUDs.

And thus, the Cruxen became our Social Network. Long before Facebook was even a glimmer in Mark Zuckerberg’s eye, we were using the Cruxen as a sort of proto-Facebook. But unlike Facebook, this was totally ours. As long as we didn’t interfere with the running of the system, we were free to explore and create and program whatever we wished.

For the next four years, the Cruxen remained central to my campus life. I made many friends all over the world through IRC and MUDs, and stayed connected to my local friends through email, msg, and talk. I posted frequently to Usenet and kept up with the goings on of the Usenet community. And I even used the cluster for real work, from time to time.

And then, only a few short years later, they were gone. For a while after I left Cornell I was still able to log on and use the system as an alumnus, but that didn’t last long. Soon I started to hear rumors that the systems were going to be put out to pasture, and I think the Cruxen were shut down in late 1998.

So that was it. The entire Crux cluster lasted from 1991 to 1998, and my involvement in it only from 1992 to 1996. Not long at all, in the grand scheme of things, but long enough to have made a huge impact on my life.

I still think about them from time to time, rather fondly. I know many people in many schools during that time probably had a very similar experience. But what sticks with me now is how brief a time college is, and how brief a window in history timesharing systems like that had. It makes me wonder how similar it was for students and faculty at SAIL or the MIT AI lab who had TOPS-20 systems, and for all the countless students who were on BITNET and VAX/VMS systems in the 1980s and 1990s. I’m sure we were not alone.

I also marvel at how different the world is now, just 25 years later, when everything is walled gardens and we’ve sold our privacy to the lowest bidder. Instead of trusting our local system administrator not to read our email, we know for a fact that Google and Facebook read our every message with the goal of finding just the right ads for us, but we just accept it as a cost of doing business. What have we lost, and what have we gained, I wonder? I don’t know.

The WATs of JavaScript

At CodeMash 2012, Gary Bernhardt gave a now infamous lightning talk that has become known simply as The WAT Talk, in which he presents several of the more surprising behaviors of Ruby and JavaScript. I’ve passed the video around quite a few times, and I’ve pointed out some other JavaScript behaviors that seem pretty outlandish at first sight. But I’m feeling a little guilty about poking fun at JavaScript, so I wanted to dive further into these WATs and talk about why they happen.

I’m not here to defend JavaScript — it doesn’t need my defense. It’s not a perfect language, and it’s not my favorite language, but it is the single most popular language on the web right now, and because more and more people are using it for the first time, I think it’s worth the effort to go over some of these unexpected behaviors to help newcomers avoid common pitfalls.

But first, the WATs.

The WATs

> [] == []
> [] == ![]
> [] + []
> [] - []
> [ null, undefined, [] ] == ',,'
> [] + {}
'[object Object]'
> {} + []
> Math.min() < Math.max()
> 10.8 / 100


Background: Type Coercion

I’m putting the cart before the horse a bit here, but I’m going to go ahead and spoil bits of the rest of this post by telling you up-front that many of these WATs involve type coercion. JavaScript is a dynamically typed language, but it is also a weakly typed language, meaning that variables may be automatically changed from one type to another in fairly wide contexts. Coercion is distinct from casting, in which a variable is changed to another type, but only if you’re changing the interpretation of its contained data or if the new type is higher up in the same type hierarchy. For example, in Java when you cast a long to an int, you’re asking that the top 32 bits be ignored and the remaining bits be treated as a 32-bit signed integer; when you cast a String to an Object, you’re asking the compiler to treat calls to the reference as if they were calls to an instance of Object.

Type coercion, on the other hand, is happy to turn an int into a String for you. In a language like Java, it happens only in a very few places, and is usually pretty obvious and easy to predict. If you’re used to these rules, though, JavaScript’s coercion can be pretty surprising. Not only will it turn a Numeric type into a String for you, but it will go the other direction too.

And now, without further ado, on to the list of WATs.

WAT Number One: Empty Array Not Equal To Empty Array

[] == [] => false

There’s actually a lot going on here. At first glance, it looks absurd: an empty array does not equal itself?! But that’s not really the question we asked.

So, what question did we ask? Like a Facebook relationship status, it’s complicated. JavaScript’s double-equals equality operator has a fairly extensive set of rules that make it more difficult to use than the double-equals operator in other C-like languages.

What we’re really asking here is, “Is one instance of an empty array equal to another instance of an empty array?” In JavaScript, the answer is no, because when you’re comparing two instances of the same type, double-equals will return true if and only if they are the same instance. We’ve created two instances here, one on the left side of the operator, and one on the right side of the operator. They are not the same instance, so [] == [] evaluates to false.

WAT Number Two: Empty Array Equals Bang Empty Array

[] == ![] => true

OK, now what is this nonsense?

Although I agree it’s pretty confusing, it’s not nonsense if you know the rules and if you apply them in the right order. Here, the bang operator binds more tightly than the double equals, so the first thing we have to do is evaluate ![]. It so happens that in JavaScript, the bang operator coerces whatever it’s applied to into a boolean value. An empty array, in JavaScript, is considered “truthy”, so when it’s coerced into a boolean, it becomes true, not false, and the bang operator converts the true into a false. Now the question looks more like this:

[] == false => true

OK, but that still looks bizarre, right? We just said that an empty array was truthy, not falsy, and true certainly does not equal false!

But, like I said, double-equals is complicated. The rules say that when you’re comparing an Object on the left and a boolean on the right, you convert both sides to numbers (the same as applying the Number() function), and re-run the comparison.

In JavaScript, Number([]) => 0, and Number(false) => 0, so now we have a new question:

0 == 0 => true

That’s more like it. Yes, zero is equal to zero.

WAT Number Three: Empty Array plus Empty Array Yields Empty String

[] + [] => ''

This is actually fairly straight-forward once you understand that the addition operator in JavaScript only operates on two types: Strings and Numbers. We’re asking JavaScript to add two Arrays, which it doesn’t know how to do, so it coerces them both into Strings and then concatenates them together. Calling [].toString() yields an empty string, and concatenating two empty strings together yields an empty string.

WAT Number Four: Empty Array minus Empty Array Yields Zero

[] - [] => 0

This case is very similar to the previous case, except we’re using the minus operator instead of plus. Again, JavaScript doesn’t know how to subtract arrays, and while Strings can be concatenated with the plus operator, Strings don’t understand the minus operator at all, so JavaScript coerces both sides into Numbers for us, instead of Strings. If you call Number([]) in JavaScript, you get 0, so what we’re really saying is:

0 - 0 => 0

That makes a lot more sense.

WAT Number Five: An Array Of Values Is Equal To A Weird Looking String

[ null, undefined, [] ] == ',,' => true

Woah, hey now. What’s this all about? It’s all about coercion and that double-equals operator again.

Here, we are using double-equals to compare an Object and a String. The rules say that when you’re comparing an Object on the left side and a String on the right side, you have to perform some operations to the left hand side to figure out how to do the comparison. The end result of this is that the array on the left is coerced into a String (by calling its toString() function, if it has one). And it just so happens that calling [null, undefined, []].toString() yields the String ",," (Why? Because null, undefined, and [] all turn into empty strings, and JavaScript joins those empty strings with commas). So we’re really asking if two strings are equal:

',,' == ',,' => true

Yes, they are, so it evaluates to true.

WAT Number Six: Array Plus Object Yields The String “[object Object]”

[] + {} => '[object Object]'

This is still more type coercion. We’ve already discussed how the addition operator only operates on Numbers and Strings, and what’s happening here is JavaScript converting both sides of the operator into Strings. An empty array, as we’ve already seen, gets converted into an empty string. But what about {}?

In JavaScript, {} is (usually!) an Object literal. It’s really saying, “Make an instance of Object for me, please.” So now we’re concatenating an empty string, and the result of coercing an Object instance into a String.

Well, the default toString() for Object returns the string “[object Object]”. The code now becomes:

'' + '[object Object]' => '[object Object]'

WAT Number Seven: Object Plus Array Yields Zero

{} + [] => 0


Wait wait wait. We just got finished explaining how JavaScript coerces both sides into a String, right? So shouldn’t this be exactly the same as the previous example?

Well, not quite.

We’ve actually been bitten by a bizarre edge case here. JavaScript has misunderstood our intentions completely. As it scanned the line, it interpreted the initial {} not as an object literal, but rather as an empty code block. Yes, really. In essence, it has just decided to ignore it completely, and treat the line as if it were written this way:

+ [] => 0

That in itself would seem nonsensical, except that JavaScript also allows unary addition operator. Unary addition + x is equivalent to calling Number(x), so what you end up with is an empty Array instance being converted to a number, which yields 0.

WAT Number Eight: Math.min() is greater than Math.max()

Math.min() < Math.max() => false

Before we explore this, let’s look at how these functions are defined, and what they return.

Math.min() and Math.max() are being used deceptively in this WAT. Most languages define global min and max values, and JavaScript does too — but not with Math.min() and Math.max(). Instead, JavaScript gives us Number.MIN_VALUE and Number.MAX_VALUE, and these behave exactly as you would expect:

> Number.MIN_VALUE < Number.MAX_VALUE
> Number.MIN_VALUE > Number.MAX_VALUE

Math.min() and Math.max(), on the other hand, are functions used to find the min and max values of a sequence of numbers. If you use them correctly, they make sense:

> Math.min(27, 9, 13)
> Math.max(27, 9, 13)

And if you call them without arguments?

> Math.min()
> Math.max()

Why? It’s how they’re implemented. Math.min() initializes its return value to Infinity and then looks for the smallest number in the sequence. There isn’t one, so it returns Infinity. Similarly, Math.max() initializes its return value to -Infinity, and looks for the largest value. There isn’t one, so it returns -Infinity.

The final form of this makes a lot more sense:

Infinity < -Infinity => false

WAT Number Nine: Floating Point Madness

10.8 / 100 => 0.10800000000000001

This is probably the sanest WTF on the page. If you’ve ever worked with floating point numbers in any language, this kind of thing is probably already familiar to you. It’s just a run of the mill floating point accuracy issue.

But 100 is an integer, isn’t it? Well, no. Not in JavaScript. JavaScript numbers come in only one flavor: IEEE-754 floating point. There are no integers in JavaScript. This may in fact be the single most important thing to know about JavaScript, especially if you’re doing any kind of math.

This problem would present itself in C, too. Example:

#include "stdio.h"

int main(void) {
	float f = 10.8f / 100.0f;
	printf("%.16f\r\n", f);

If you run this code, what do you get? Not 0.108! On my computer, you get 0.1080000028014183, because of inherent limitations in floating point accuracy.

JavaScript isn’t alone here, it’s just more likely to bite you because you have to use floating point, while you’re free to use other numeric types in other languages.


I’ll be frank: JavaScript is weird, but it’s here to stay, and if you find yourself working in it, it’s good to immerse yourself in the weirdness and try to get a feel for what’s going on under the hood. I hope this post has helped to clear up a handful of the stranger seeming cases, especially if you’re new to it and coming from the background of another language.

Do You Want To Build an FPGA? Part Two

In my last post, I showed you how to download Altera’s Quartus II software and get a new, empty project started for the BeMicro CV platform.

This time, we’ll learn how to build a Verilog module and compile it.

The Blank Slate

We left off looking at a blank slate, an empty project.

Empty Project

This is always the most intimidating part of any project. What do we want to do?

The next step is to define a top-level design file. From the menu. select FileNew…, and you will be presented with a list of components. Select Block Diagram/Schematic File from the list.

New Block Diagram

Next, click FileSave As… from the menu, and save the new top level design file as flashy.bdf.

We won’t get very far with just a blank design file. We need a Verilog Module to define the behavior we want from our counter, so next, choose FileNew… from the menu, and select Verilog HDL File. This will open up a blank Verilog file, ready for your input.

New Verilog

The Verilog “counter.v” Module

Verilog is a language that defines how our FPGA is to behave. It’s tempting to think of it as a programming language, but it’s dangerous to fall into this trap. It’s not a programming language, it’s a hardware definition language.

What’s the difference? A programming language describes linear process that implements an algorithm step-by-step. A hardware definition language, on the other hand, describes how a digital circuit should behave using words. It is not implementing an algorithm, it’s implementing a circuit!

The distinction can seem very subtle. When you’re describing how hardware behaves, it can certainly look very much like a program or an algorithm. But it’s not, and it’s always very important to keep that in mind. So, we want to design a circuit that will take a 50 MHz clock signal as input, and count down on the 8 LED outputs forever.

Here’s our Verilog module to describe that behavior. Save this file as “counter.v”:

Verilog Module

It’s short and sweet. The top-level module definition has two arguments, clk_50, which we will map to our 50 MHz clock signal, and leds, which we will map to our LED outputs.

Internally, there are two registers: an 8-bit register named leds, and a 21-bit register named counter. These are used to latch state in the circuit. Because we’ve named one of the registers the same as one of the outputs, they will be automatically connected for us.

The critical part of the circuit description is the always @(posedge clk_50) block. This describes what happens at the positive edge of a clock trigger on the clk_50 input. It says that we decrement our counter register, and if the counter happens to be all 0’s, we latch the state of the LEDs plus one into the leds register. We’re using the internal counter register as a delay to slow down the rate at which we update the LEDs.

You may be confused at this point, because I said our circuit was going to count down, but clearly we’re incrementing the leds register. What’s that about? Well, it turns out the BeMicro CV uses LEDs that are active low, meaning that they light up when the corresponding output is grounded. The end effect is that if you want all the outputs lit, you write 00000000 to the output. In other words, when we count up with our leds register, it looks like the LEDs are counting down. If you wanted the LEDs to count up, you could just invert the output. I’ll leave that as an exercise to the reader.

Adding the Verilog Module to the Project

We’ve described a simple circuit here. Now we need to tell Quartus how to connect the inputs and outputs of our circuit. To do that, we’ll first need to make a circuit diagram symbol for our module.

Right-click on the “counter.v” file in our project, and select Create Symbol Files for Current File

Symbol File

Quartus should compile your file. If you get any errors, double-check to make sure there are no typos! After it’s compiled, you can close the Compilation Report tab, and then return to the flashy.bdf tab.

Right-click anywhere inside the flashy.bdf tab, and select InsertSymbol… from the context menu.

Insert Symbol

You should be presented with a dialog like this. Select the counter symbol from the Project folder, click OK, and then drop the symbol anywhere into the flashy.bdf tab.

Counter Symbol

Now we have a symbol placed into our project, but we still need to map its inputs and outputs. Right-click on the symbol you’ve just placed, and select Generate Pins for Symbol Ports from the menu.

Generate Pins

There, now things look a little more complete. We can see that we have some pins named clk_50 and leds[7..0].


Connecting The Pins

Although our symbol now has inputs and outputs, those inputs and outputs are not yet connected to the real physical BeMicro hardware! To do that, we’ll need Quartus’s help.

From the menu, select ProcessingStartStart Analysis & Elaboration. This step will analyze our top-level schematic and figure out how many inputs and outputs we’ll actually be using on our FPGA chip.

Start Analysis

The module will compile, and Quartus will analyze it. Depending on your hardware, this may take a minute or two. You should eventually see a compilation report letting you know the analysis was successful. You can close the compilation report once you’re done reviewing it.

Analysis Report

Now comes the critical part: We can map our circuit’s inputs and outputs to real FPGA pins!

From the Assignments menu, select Pin Planner

Pin Planner Menu

You should be presented with the Pin Planner. This dialog allows you to map the flashy inputs and outputs to the FPGA’s pins. You’re actually looking at a real map of all 484 pins on the FPGA, but don’t worry — we’re only going to be using nine of them!

This is where we have to turn to the BeMicro’s documentation for help. We want to figure out what input the 50 MHz clock is on, and what outputs the LEDs are on. I’ll save you some time and pain by just putting the information here, because it turns out that the BeMicro CV documentation is wrong. Their mapping of LED pins is out of order. Oops!

Here’s how the BeMicro CV actually maps its pins:

FPGA Pin Voltage BeMicro Mapping
H13 1.8V 50 MHz Clock

We need to map these using the Pin Planner. In the end, your Pin Planner should look like this:

Pin Planner Mapped

It’s safe to close the Pin Planner window now, and you’ll notice that the symbol has changed somewhat, to show that the inputs and outputs have been mapped.

After Mapping

Now you’re ready to compile the whole project. From the Processing menu, select Start Compilation. Compiling should take a minute or two, depending on your hardware.

Once it’s all done, congratulations! You’ve built your first FPGA module! Now all you need to do is actually load it onto the FPGA and start it running. We’ll cover that in our next and final blog installment.

Rural Cable Expectations

My story kind of hit social media hard this week. To say it caught me off guard is an understatement. I never in a million years expected the response to be so big. I’m just some guy, I don’t particularly enjoy all the attention suddenly paid to my problem. But, that said, I’m grateful for all the support and tips I’ve received, and I’m investigating all connectivity options.

One of the frequent criticisms I’ve seen goes something like this: “Well, you moved to a rural area, what did you expect? Even though Comcast said it was serviced, you share some of the blame for even expecting cable out there. You should have known better!”

Well, I disagree pretty strongly with this criticism. Let me tell you why.

Here’s a picture of where I grew up. It’s in rural Connecticut, about a half hour east of Hartford. The whole “neighborhood” (if you can call it that) had cable TV as of 1988. Please note, too, that many of the homes you see to the north weren’t built until the late 1990s and early 2000s, so the area was even less dense then than it is now.

Rural Connecticut

Cable broadband came to this area later, of course. It wasn’t installed there until about 2000, when the infrastructure was upgraded to allow DOCSIS. My aunt lives there now, she has great 25 Mbit broadband through Cox. So, yes, frankly, I did expect that cable could be here.

And what about now, today, in Washington State? Here’s another satellite view of part of Kitsap county, the county I live in.

Less Rural Washington

Here is where it gets weird. Notice the fairly dense neighborhood to the north of the highway? That area is completely unserviced. Comcast’s internal maps, which I have seen, show that the whole neighborhood is wired with Comcast cable. But, in reality, it’s not. There’s no cable there, Comcast has no customers there.

Meanwhile, the road to the south, which is more rural, with a mix of houses on 5 acre lots and farm land, is fully wired for Comcast.

So, yes, I did expect that cable would be a thing that this part of the county could do. It is not that unusual here. In fact, the neighborhood to the north is an exception, not the rule.

But all that should not distract from the core problem, here: Comcast told me that my address was already serviced. That is what I relied on, not some mystical third eye that could show me underground Cable TV infrastructure.

Do You Want To Build an FPGA? Part One

My internet fiasco aside, I think it’s time I start getting back into some technical matters here on the blog. So welcome to the first in a series of posts about FPGA development!


If, like me, you’ve always wanted to try your hand at programming an FPGA, there’s no time like the present. FPGA kits that are accessible to hobbyists have become affordable and plentiful! One of the most affordable is the BeMicro product line from Arrow and Altera, with kits starting at $30 and going all the way up to $149.

I recently bought the BeMicro CV package to play around with. The BeMicro CV is a nifty little $50 FPGA development board with an Altera Cyclone V FPGA, 128MB of on-board SDRAM, and 2MB of Flash memory. It’s also got a two push-buttons, three DIP-switches, and a MicroSD card slot available for your projects to use. I think it’s an ideal platform to get your feet wet in the world of FPGA development. But after you get your BeMicro CV out of the box, what do you do with it to get started?

The Tools

Altera FPGAs are programmed with the Quartus II suite of software. There are versions for both Windows and Linux available. For this Tutorial I’m using the Windows version because it felt like the path of least resistance.

If you’re used to developing software with an IDE, it’s not too dissimilar at first glance, but don’t be fooled! It’s more like an IDE on steroids. The Quartus II download is massive, weighing in at roughly 5.2GB for the full package. Given my current broadband woes, I visited a nearby coffee shop to download my while I sipped on a tasty beverage.

Downloading Quartus II

This is perhaps the most annoying step. I think it’s time for Altera to accept that hobbyists are using their tools, and make the process a lot easier.

The Quartus II Web Edition is totally free to download and use for your hobbyist projects, but in order to do so you’ll have to register with Altera and create a user profile, complete with a lot of information that really only applies to companies.

To download Quartus II, follow this link.

By default, you’re downloading the entire package with files for all sorts of different Altera devices. If you’re on a slow connection or you would like to save a little bit of disk space, you can choose to download only the files necessary for the BeMicro CV board by selecting the Individual Files tab, and under Devices, de-selecting everything except Cyclone V device support. (Remember, the BeMicro CV is a Cyclone V, so you need that!)

You’ll be prompted to register for an account when you try to download. I won’t walk you through this, it should be fairly self-explanatory. Use your best judgement here to decide what you need to enter when it comes to things like company name and company data.

When you’re done and logged in, go back to the download page and continue to download the software. It’ll take a while. Enjoy some quality time with coffee or tea.

Setting Up Quartus II

Once everything is downloaded, double-click on the installer and follow the instructions. I just used the defaults throughout the installation.

After Quartus II is installed, double-click the Quartus II icon to get started.

Quartus II Icon

The first time you run Quartus II, you’ll have to click through a dialog box to let it know you want to run the software without buying a license:

Quartus II first launch

Finally, you should be greeted by something of a blank slate, ready to create a new project.

Quartus II New Project

Your First Project

We’re going to walk through a very simple project. The goal of this exercise is to get the 8 user-programmable LEDs on the BeMicro CV counting down in binary from 11111111 to 00000000 forever, in an infinite loop. It should be fast enough to look cool, but slow enough for you to see it actually happening. I’m calling this project “Flashy”.

To get started, click on the New Project Wizard link in the middle of the IDE. This wizard will go through the steps of setting up our project.

At the first dialog, enter a location and name for your project. I’ve named my project flashy, and put it into a folder on my Desktop, under C:\Users\Seth\Desktop\Projects\flashy. Then, click Next.

New Project - Name

On the next dialog, click Empty Project, then click Next again.

Empty Project

The next dialog asks if you’d like to add any files to the new project. We don’t, so just click Next.

Add Files

The next dialog is critical! It asks us to pick which device we’re going to target. To narrow down the choices, select the following from the pull-down menus:

  • Family should be Cyclone V (E/GX/GT/SX/SE/ST)
  • Devices should be Cyclone V E Extended Features
  • Package should be FBGA
  • Pin count should be 484
  • Core Speed grade should be 8
  • Finally, under Available Devices, select 5CEFA2F23C8

Be absolutely sure that 5CEFA2F23C8 is selected! This is the exact device used by the BeMicro CV, it must match the chosen device. Then click Next

Device Selection

The next page in the Wizard is the EDA Tool Settings page. The only thing we need to change here is the Simulation Format. Pull down the menu and select Verilog HDL, then click Next.


The final page just asks you to verify everything. Make sure the Device is 5CEFA2F23C8, then click Finish.


Congratulations, your shiny new blank project is set up and ready to start working on!

In our next entry, we’ll look at how to write your first Verilog module and compile it.

It’s Comcastic, or: I Accidentally Bought a House Without Cable

UPDATE: Be sure to read my follow-up post. Spoiler Alert: It has a happy ending!

Jump to the FAQ

This is a very long post, but it needs to be long to properly document all the trouble we’ve gone through with Comcast. In short: We moved into our new home in January after verifying that Comcast was available. They said no problem, and we ordered their service. After moving in, and only after a month of confusion and miscommunication, we discovered the truth: There’s no Comcast service on our street.


Late last year we bought a house in Kitsap County, Washington — the first house I’ve ever owned, actually. I work remotely full time as a software developer, so my core concern was having good, solid, fast broadband available. In Kitsap County, that’s pretty much limited to Comcast, so finding a place with Comcast already installed was number one on our priority list.

We found just such a place. It met all of our criteria, and more. It had a lovely secluded view of trees, a nice kitchen, and a great home office with a separate entrance. After we called (twice!) to verify that Comcast was available, we made an offer.

January 29, 2015

This was our first interaction with Xfinity. Earlier in the month we had placed a separate order with Comcast Business for stand-alone Business Internet, but they said they couldn’t provide us with service, so they cancelled the order on us. They suggested that we contact Xfinity and get consumer TV and Internet instead. That sounded like a fine idea to us, we like TV! So that’s what we did.

We ordered our service on January 29th. We went with the Digital Starter package and the “Blast 105” Internet service with a 2-year contract, very standard. They told us that we would have a tech visit us to do the install on January 31st between 10 AM and 12 PM.

January 31, 2015

The tech came out as scheduled. The first thing he expressed to us was surprise that we didn’t already have a Comcast box on the side of the house. We searched the property, and in fact, there was no Comcast box anywhere. Now, there is a coax utility box, but it wasn’t Comcast’s. That originally confused both of us, but on further inspection, the utility box with coax running into it used to be hooked up to a satellite system on a pole near the house (with the dish now removed), so it wasn’t CATV at all.

The tech told us that in order to get service, we’d need to have coax run from the road to our house, which would probably also involve installing a new service pedestal along the way. He called to set that up for us, and told us he was going to do something called a Drop Bury Request to bring in service. He filed a ticket and went on his way.

February 3, 2015

Not having heard anything from Comcast, we called them on the 3rd to confirm the Drop Bury Request. They gave us a ticket number (#027246726) and promised us that someone would call or email us about it.

February 6, 2015

We hadn’t heard anything from Comcast, so I placed a follow-up call to their support line. We were told nothing. The support person couldn’t even look up our ticket number for us, so we ended the call.

I decided to call back a few hours later and spoke with someone named “Walter”. They were also no help. So I called back a third time and spoke with “Leila”, who scheduled another tech visit to come out and see what was going on on February 9th.

Around this time, we had an un-expected and un-scheduled visit from a technician, before the 9th. Regrettably, I didn’t write down his name or the exact date of the visit. He just appeared out of nowhere and asked us where our cable box was. We explained that we didn’t have one, but that we did have a Drop Bury Request in place. He looked perplexed. He told us that there was no way a Drop Bury Request could possibly get us hooked up, we were too far away from the cable infrastructure. We asked him to contact someone at Comcast to get things resolved, and he left.

Februrary 9, 2015

The scheduled tech dropped by on the 9th, as promised. Just like the previous two techs, he had absolutely no notes on his work order about any Drop Bury Request, any pedestal, or any construction. He just showed up expecting to hook up a cable box and go on his way.

We explained, yet again, that we did not have cable service to the house, and that we were trying to find out how to get it serviced. He couldn’t help us, but he promised to escalate the issue to Comcast Engineering.

Well, that sounded extremely promising. He said that Engineering would be able to get things moving, and then he left.

February 12, 2015

On the 12th, I called and spoke with a Comcast salesperson named “Lee” to ask about progress. There were two big issues on my mind. First, what does “serviceable” mean? All along every step of the process, Comcast kept promising us that our property was “serviceable”. What precisely does that mean? The Comcast support agent told me that “serviceable” meant that there was a cable run to the house.

That was a bit of a stunner. I explained, very clearly, that there was no cable run to our house at all. How can our property be called “serviceable” if there’s no cable here? They didn’t really have an answer for me.

But, more importantly, the second issue I wanted to know about was the progress on the Comcast Engineering request. I was put on a brief hold, and the support agent came back to tell me that they were working on it. His exact words were, “They assured me that they will bring you service.”

That was good enough for me, I figured things were moving along fine.

February 13, 2015

I just wanted to follow up on the Engineering Request and get more information, so I called again on Friday the 13th to find out what the next step was. I spoke with a sales support agent named “Jessica”. I explained the history of my requests, and she looked at all the notes on my account. At this point she put me on a lengthy hold to “speak with Engineering”.

She came back onto the line and told me that things were progressing just fine. Good news! They’re just in the process of pulling permits for construction, which can take a long time. She said they might have some more information in about a week.

Well, I was overjoyed. I figured that was that, the wheels were finally moving. Little did I know.

February 17, 2015

Again, I wish I had written down the exact date, but another tech came by unannounced. Just the same as the other techs, he had no knowledge of any engineering request, no knowledge of any Drop Bury Request. And, just the same as the other techs, he thought he was just going to install a cable box and go on his way. Needless to say, there was nothing he could do, so he left.

We had a second visit shortly after that from a site surveyor, who said he was just looking for the nearest cable node. He wasn’t there to bring us service, just do surveying. He mumbled something about how it was going to be a very expensive job, then left.

February 20, 2015

So, I gave it about a week. I called back on the 20th to find out what progress had been made. I spooke with “Matt” in Sales.

Matt looked at my notes, and said he couldn’t find anything about an engineering request. He said that engineering doesn’t necessarily update your notes anyway, so it wasn’t that surprising, but there was a bigger problem: He said that my order had “timed out” because it sat so long. He would need to re-order service for me.

I was floored. “Timed out?” How can that even happen?

Anyway, I took the opportunity to upgrade my order to an even more expensive plan, hoping that “greasing the wheels” of capitalism would make the process move a little faster. I asked for the works—The Digital Preferred bundle with TV, Internet, telephone, HBO, HD, the whole shebang, with a two-year contract. Couldn’t hurt, right?

“Matt” then told me that in cases like this, Comcast can often do a “temporary drop” to get service started while waiting for construction. Well, awesome. I didn’t actually expect a temporary drop to work, but I figured it was worth trying. So he scheduled a tech to come out between 8AM and 10AM on the 21st.

February 21, 2015 – Morning

The tech showed up at about 9 AM. The very first thing he said was, “I hate to tell you this, but I don’t think you have cable!”

Wow. Really? Do you think?

Just like each and every tech that had come out before, this one had absolutely no notes on his work order about our situation. He was just there to hook up cable. He said there was no way he could do a temporary drop because we didn’t have cable run to the house. He left.

February 21, 2015 – Afternoon

At this point I called Sales again to figure out what my status was. I spoke with “Pat”. What Pat said shocked me. According to her notes, the work was done. On the 17th, she claimed, the survey work was done. Then, on the 21st (the same day) the installation was done. So, according to her, we now had service.

I explained that no, we did not have service. No outside work had been done. No construction had been done. No engineering work had been done.

To move forward, we had to open a whole new order for service, same as before.

And what about that Engineering request? Well, Pat couldn’t find any reference to an Engineering request. She saw nothing in my notes to indicate that any Engineering request had been made.

She opened a new “ER-1” Engineering ticket (#027574739) for me and promised that I would be called or emailed within 24 hours.

February 22, 2015

I gave them their 24 hours and heard nothing, of course. I called back and spoke with “Mark” in Sales. He looked over my notes, and told me that the ER-1 ticket had been closed as an “invalid ticket” because it did not involve a Drop Bury Request.

To his credit, Mark seemed pretty shocked at how I had been treated. I explained that we’d been visited by six techs so far and all of them had said the same thing. I explained that we’ve been trying to get new construction. I explained how frustrated I was.

I think this was the most productive call I’ve had so far, because I finally got the clear picture of what’s going on. Somewhere in Comcast’s system, there’s a check box that says that I already have cable service to the house. Every time I call to ask about new service, someone looks at this checkbox and concludes that I don’t need construction. Whenever a ticket is opened in regards to construction, it’s closed automatically because the system believes it’s not necessary. So I am literally in a Catch-22.

Mark did give me a good lead. He gave me the phone number for the Comcast New Construction Department (1-866-772-2281) and told me that I should give them a call on Monday. They deal with new home construction, subdivisions going up and so forth, so they may not be exactly the correct department to call, but hopefully they will have more information than Sales has.

Mark also claims that he has opened a New Serviceability Check request. I anticipate that nothing will come out of that.

February 25, 2015

This has been a very interesting week.

On Monday, this very blog post made its way to the Comcast planning office via a follower on Twitter who (and I promise I did not know this) works for Comcast. They called me almost immediately and were very apologetic about the entire situation, on a personal level.

This led to a serviceability engineer coming out to measure the exact distance from our house to the nearest Comcast plant. It turns out to be approximately 2500′.

I was given a very rough initial estimate of $20 per foot to do the line extension work. Now, that sounds high to me. I don’t know what will come of this, but at least there’s some movement going on, and that’s more than I could have dreamed possible a few weeks ago.

The next step will be for their engineering department to work out exactly how the cable would run, via what poles, how much is underground, etc., and come up with a final price.

February 26, 2015

Oh, this is fun. I got a call from a generic Comcast call center this morning asking me why I cancelled my latest installation appointment. Insult to injury, they started to up-sell me on all the great things I’d be missing out on if I didn’t reschedule! I just hung up.

I don’t anticipate this had anything to do with the line extension. It was just what happens whenever you cancel an installation, I guess. Still, I cursed under my breath.

March 2, 2015

It’s now been 34 days since the saga began. Right now, things are in a holding pattern. I’m still waiting to hear back from Comcast about what the total cost for a line extension will be, and I’m sure it could take a few more days (at least) to get the results from Engineering.

In the meantime, I have done a tremendous amount of research about CATV infrastructure, and learned more than I ever really wanted to know about it. In addition, I requested and obtained a copy of the franchise agreement between Kitsap County and Comcast so I could better learn about my rights and Comcast’s obligations in providing new service.

I think the take-away of this whole thing so far can be summed up in two bullet points:

  • Never trust Comcast Sales when they tell you that service is available. Verify if yourself, and if that means you need to spend two weeks studying up on CATV infrastructure so you know exactly how to spot trunk line, line extenders, taps, and HFC nodes, then do it.
  • Know your rights. Always request a copy of your CATV franchise agreement and read it thoroughly. They’re usually quite long, and full of legalese, but it’s worth it.

March 12, 2015

It’s been a while since an update, but there’s just not a lot of news right now.

Last Thursday, the 5th, two engineers from Comcast (Robert and Ken) came out to do another survey in preparation for a final engineering design. I’ve been warned that the initial, pre-survey price estimate was between $56,000 and $60,000 for the extension. Now, I wouldn’t have to pay all of that out of pocket — Comcast is supposed to pick up part of the cost, but I don’t know how much.

I haven’t heard anything else from Comcast since March 5th, and I don’t know what the final estimate will be. I don’t know how much I’ll have to pay out of pocket, and I don’t know how long it will take. So, that’s where we stand.

In the mean time, we’ve started to look at excavators who could do the trenching work for us. If it would be cheaper for us to do the trenching rather than Comcast, I’d rather go that route. It might save a significant amount, I don’t know.

There is still so much left unknown. The waiting is the hardest part.

March 20, 2015

This is a hard update to write.

We got bad news on Wednesday, the 18th. At about 3:45 PM, Robert called and told me that Comcast will not do the extension. No ifs, no ands, no buts, they just won’t do it. They wouldn’t even give me the chance to pay for it. Too much effort on their part.

I’m devastated. This means we have to sell the house. The house that I bought in December, and have lived in for only two months.

I don’t know where we go from here. I don’t know if there’s any kind of recourse. I do know that throughout this process, Comcast has lied. I don’t throw that word around lightly or flippantly, I mean it sincerely. They’ve fed me false information from the start, and it’s hurt me very badly.

This whole thing would have been avoided if only Comcast had said, right at the start, that they didn’t serve this address. Just that one thing would have made me strike this house off the list.

I don’t know exactly how much money I’m going to lose when I sell, but it’s going to be substantial. Three months of equity in a house isn’t a lot of money compared to sellers fees, excise taxes, and other moving expenses.

So, good bye dream house. You were the first house I ever owned, I’ll miss you.

Frequently Asked Questions

I wanted to address a few FAQ’s about this post, this seems like a fine time to make some clarifications.

  1. Q: Why Didn’t you check this before you moved?

    A: Oh, but I did. Having broadband of some kind was an absolute requirement for our new home. Before we even made an offer, I placed two separate phone calls; one to Comcast Business, and one to Xfinity. Both sales agents told me that service was available at the address. The Comcast Business agent even told me that a previous resident had already had service. So I believed them.

  2. Q: Why didn’t you get this serviceability status in writing?

    A: I tried. When I asked for serviceability in writing, I was told it just wasn’t something Comcast could do, that they have no process for it. We were simply assured, verbally, that there was service here. And, besides, they clearly did believe that I was serviceable, or they wouldn’t have sent six techs out to hook me up.

  3. Q: Didn’t you even check to see if the house was wired yourself?

    A: We did. The house is actually loaded with coax. There’s a coax drop in almost every room, in fact. Moreover, on the side of the house is an unmarked grey box that feeds the coax into the house. From this box, two coax cables disappear underground. So, to our (at the time) untrained eyes, this sure looked like CATV infrastructure.

    It turns out, though, that this was satellite. Years ago, a previous owner had satellite TV, and the underground coax used to feed a dish that is no longer there, on a pole next to the driveway.

  4. Q: Shouldn’t you have expected that your rural property didn’t have cable? Why were you surprised?

    A: I’ve addressed this question in a whole new post

  5. Q: What about other options? Have you looked at DSL?

    A: You bet we have! Our local provider here is CenturyLink. I called them almost immediately after the first tech said we didn’t have service. We were told “No problem! We’ll get you hooked up right away.” The very next day, they called me back and corrected themselves. “Actually,” they told me, “it turns out your area is in ‘Permanent Exhaust’, so we can’t add new DSL customers. No, we have no plans to upgrade anything. So sorry, and bye!”

    Needless to say, we were not happy.

  6. Q: Lots of places have fixed point-to-point wireless. What about that?

    A: We also looked into this very quickly. In fact, there is a wireless provider that serves much of Washington (StarTouch). I called them to inquire about pricing, but was stopped short. “I’m very sorry. We used to serve your area, but last year somebody built a building between our tower and Poulsbo. We lost a lot of customers. There’s nothing we can do for you.”

  7. Q: What about wireless networking with a neighbor?

    A: We haven’t ruled this out yet, but a couple of things make this very challenging. First, our terrain makes it pretty difficult. We have trees here, big trees. To establish a clear line of sight to any location with broadband would require us getting above the tree line, which is about 100 feet (30 meters). We’d need to build a large tower just for that. Second, point-to-point wireless is degraded in the rain. We live in Washington. It rains here a lot. And finally, it may be difficult to find a neighbor willing to work with us. All that said, it is absolutely still worth investigating.

  8. Q: Well, what about Satellite?

    A: The TV service would be just fine, but it carries a huge penalty for broadband. I work remotely full-time, and I require a VPN to access the main office. Satellite does not guarantee any support for VPN use (though I have heard a few anecdotal reports of people having success). The monthly bandwidth caps are also a killer, giving very little leeway in overage situations.

  9. Q: How are you getting any work done right now?

    A: I’m living off of a Verizon JetPack mobile hot spot. It’s frightfully expensive and has a 30GB per month cap, but it allows me to get my work done, at least. I spend all day on a VPN back to company HQ and use close to a gigabyte a day, so I bump up against the 30GB cap every month. That means I have to be pretty careful with my data use. No streaming, no games, nothing fancy.

    When I want to download a big file, like an OS update or a VM image for work, I go to the local Starbucks. Their Wifi is great.

The 1993 Social Network

I was a freshman at Cornell University in Fall of 1992 when I logged into my first UNIX system.

I’d heard of UNIX before, of course—it was a popular subject in trade magazines of the period, and if you tinkered with computers you’d probably have heard of it—but I’d never actually used it. So one day I marched over to the campus IT department to register for a UNIX account. It took some wrangling, but very shortly I was drinking from the UNIX firehose.

Compared to a lot of other schools, Cornell’s UNIX cluster was small and under-powered. Resources were scarce. The whole campus had to share four DECstation 5000s running ULTRIX with home partitions mounted over NFS, so they actively discouraged new users. I don’t remember the specs (you can use your imagination) but I do remember how laggy things got when there were 30 or so users logged into each system. We called this cluster “The Cruxen”, because the systems were named crux1, crux2, crux3, and crux4.

The thing that made this cluster special was not the hardware or the software; it was the community that formed around it. By mid-1993, a great many of my friends had accounts on the Cruxen, and it didn’t take long for the cluster to become a place to meet, talk, share ideas, and kvetch. One of the most common ways to talk to each other was the UNIX utility write, which allowed you to send a short one or two line message to a user logged in on another terminal—long before the term ‘instant messanger’ had been coined, we were doing it on UNIX. We used last and finger to see when someone had last logged in, and to watch for them to log in again. For more immediate, longer-form communication, we used talk to connect two terminals together and watch each other type back and forth. And of course there was always e-mail, and Usenet, a global network of hundreds of computer bulletin boards covering every subject under the sun. The Cruxen were a social network, as surely as Facebook is today.

Really, it was more than a social network. It was a Social Network++, a fully programmable social network. Interesting projects sprang up on the Cruxen. It was easy to share scripts and coding projects back and forth when everyone had access to the same filesystems, programming languages, and tools. Of course sometimes disasters happened, but they were rare. Once, a friend built a distributed queue manager for POVray rendering, so that all the Cruxen could render an animation frame in parallel. He did not leave enough idle time, and ended up taking down the whole system. I myself once almost took it down by seeing what would happen if I created a .forward file that forwarded email to myself (discovery: it formed an infinite loop and quickly filled up the mail spool, bringing upon me the wrath of the admins). It was immense fun, and we felt like we were on the cutting edge.

But the fact is, we were late to the game. This scene had already been played out many times and in many places. From the late 1960s onward, big multi-user computer systems were places where people could form communities, whether running MULTICS or TOPS-20 or ITS or UNIX or VMS. This sort of thing was common-place in those environments. By the time we found the Cruxen in the early 1990s, the timesharing experience was already on the wane. By 2000, it was largely a thing of the past. Desktop computers that could do everything the UNIX cluster could do were cheap and readiliy available, and there was no need for a shared environment any more. Each of us now computes alone.

Is there any way to recapture this sort of experience? Yes! One of the oldest and best known is the SDF Public Access UNIX System. They’ve been in business since 1987, so they have considerable experience providing a UNIX cluster environment to thousands of users.

More recently, Paul Ford (@ftrain on Twitter) created an accidental phenomenon when he launched, a place to build and share web pages on a plain-old UNIX box, just like we did back in the ’90s when the World Wide Web was young and new and we ran with Perl scissors.

And, finally, there’s my own brand new project, RetroNET, whose goal is to give a Cruxen-like experience to hackers and tinkerers and makers.

We can never go back to the days when we had to use a cluster to get our work done, nor would I want to. But we can still recapture some of the feel of that time, and I think we can still do good things with it here in the 21st century. So, whether you’ve used a UNIX system before or not, whether you lived through that time or you didn’t, I encourage you to at least give it a try. You never know who you’ll meet, or what you’ll learn.

Retrochallenge: The Final Entry

Well. Here it is, the final entry for my Summer Retrochallenge project. I wanted to do more, but as so often happens, real life intervened and I didn’t have nearly as much time to work on it as I’d wanted. C’est la vie!

But I’m still proud of what I accomplished. I have a working ROM monitor, and I’m happy to report that as a final hurrah, I got it fully integrated with Lee Davison’s Enhanced 6502 BASIC.

Integrating with BASIC

I didn’t start this project thinking I’d tackle BASIC integration, but as Retrochallenge drew to a close, it seemed like it might be the best use of my precious time. What I mean by “Integration” here is simply having my ROM monitor code live side by side with BASIC and provide the underlying I/O functionality needed for BASIC to talk to the terminal and get input, plus the ability to take over and run in the foreground when the user wants it.

If you’ve ever used an Apple II, you may recall that it, too, has a built in ROM monitor, and it can be reached by typing CALL -151 into Apple BASIC. Well, when running Enhanced 6502 BASIC with my monitor, you can get the same thing by typing CALL -1239. Once you’re in the ROM monitor, you can quit back to BASIC just by typing Q. Like so:

BASIC Interop

It actually turned out to be fairly simple to get the integration working.

The first thing I had to do was re-organize my memory usage so as not to conflict with EhBASIC’s memory map:

;;; ----------------------------------------------------------------------
;;; Memory Definitions
;;; ----------------------------------------------------------------------

        STRLO   = $de           ; Low byte of STRING (used by STR macro)
        STRHI   = $df           ; Hi byte of STRING (used by STR macro)
        HTMP    = $e0           ; Hex parsing temp
        OPADDRL = $e1           ; Addr of current operand (low)
        OPADDRH = $e2           ; Addr of current operand (high)

        OPBYT   = $02a0         ; # of bytes parsed in 16-bit operands
        TKCNT   = $02a1         ; Count of parsed tokens
        IBLEN   = $02a2         ; Input buffer length
        CMD     = $02a3         ; Last parsed command
        TKST    = $02a4         ; Token start pointer
        TKND    = $02a5         ; Token end pointer
        OPBASE  = $02a6         ; Operand base
        IBUF    = $02c0         ; Input buffer base

There’s not much room left in Page Zero after EhBASIC gets done with it, but the locations $DE thorugh $E2 are free, so I made use of them. Page Two is similar, so I stuck my variables all the way up at $02A0 and on.

After that, I had to change the implementation of CIN a little bit, because EhBASIC requires that it not block. Instead, it expects this routine to return immediately and set the Carry flag if a character was read, and clear the Carry flag if no character was read. The new routine looks like this:

CIN:    LDA     IOST
        AND     #$08            ; Is RX register full?
        BEQ     @nochr          ; No, wait for it to fill up.
        LDA     IORW            ; Yes, load character.
        ;; If the char is 'a' to 'z', inclusive, mask to upper case.
        CMP     #'a'            ; < 'a'?
        BCC     @done           ; Yes, done.
        CMP     #'{'            ; >= '{'?
        BCS     @done           ; Yes, done.
        AND     #$5f            ; No, convert lower case -> upper case,
@done:  SEC                     ; Flag byte received, for BASIC
        RTS                     ; and return.
@nochr: CLC

It’s a little ugly and could easily be optimized at the expense of readability, but hey, it works!

So that’s it. With just those changes, I was pretty much able to integrate the monitor into EhBASIC in just a few hours. As always, all of my code is available on GitHub for your viewing pleasure.

I’d also like to add that this has been a fantastic Summer Retrochallenge. There were so many amazing projects, I can’t even pick a favorite. I’ve really enjoyed reading what everyone else has been up to, and I’m already looking forward to January. Onward and upward, everyone!

State of the Retrochallenge

As I write this, it’s early on the evening of July 25th, and I’m staring next Thursday’s deadline in the face. I haven’t been able to work on my Retrochallenge entry for over a week, and it’s in poor shape.

But am I going to give up? No way. I’m going to go down fighting.

My over-enthusiastic early plans called for me to finish up my 6502 ROM monitor so early that I’d have time to work on cleaning and sorting my RL02 packs. That, needless to say, is not going to happen. Instead, I’m going to concentrate on polishing up and documenting my monitor this weekend. Whatever I have ready to go next week will just have to be good enough. It won’t be as fully-featured as I originally wanted, but at least it’s something, and at least it works.

I have to pick my remaining features pretty carefully now. I want to enhance the Deposit and Examine commands to add syntax that will allow auto-incrementing the address, and then work on tying my monitor into EhBASIC, so I can run it on my home-brew 6502 after Retrochallenge is over.

It’s a race to the finish, now. Expect an update from me on Sunday or Monday. Until then, I’m face down in the code!