Building a 4-bit CPU TD4 (Part 1)

by Yuji Yokoo

The Motivation

Earlier this year, I have decided that I want to be a "full stack developer". In order to do that, I need to learn the parts of the "stack" I don't know about. The most obvious one, is the hardware layer. Some might say that's not what they mean by "full stack" but I'm not listening to them! Surely, you have to question how full your "full stack" is, if you don't have any hardware to run on. Well, perhaps I should start from semiconductor or metal production, electricity generation, or even inventing the universe, but I think I'd leave that till later, and focus on building a 4-bit CPU by soldering ICs and other parts together.

Why this TD4?

TD4 is the CPU described in the book I have bought about 10 years ago. This book is in Japanese and called "CPUの創りかた (CPU no tsukurikata)", or "How to build a CPU" by Kaoru Tonami. TD4 stands for "とりあえず動作するだけの4bitCPU (Toriaezu Dousa-suru-dakeno 4bitCPU)", or "4-bit CPU that runs". The book shows in detail how everything works in this CPU and shows its circuit diagrams. I had read it before but never actually built the CPU. I'm building it according to those diagrams. The author's webpage is here (in Japanese): 

This is the scanned cover of the book "CPUの創りかた". This is my copy so you can see some damage and stains but that tends to happen to good books I read a lot :)

This is the scanned cover of the book "CPUの創りかた". This is my copy so you can see some damage and stains but that tends to happen to good books I read a lot :)

Step 1 Order necessary parts

There are some resources (in Japanese) available that tells you exactly what you need in building TD4. I used this and this. I bought most of my parts from Jaycar and element14. Without much knowledge in electronics, it's quite tedious to search through element14's catalogue and buy things, and I ordered a few wrong items too. So I have some extra parts and I am not sure what to do about them. I bought way too many IC sockets by mistake too.

Step 2 Test building some bits of the system

Without any background in electronics, engineering, or hardware in general, I decided to test-build some parts of the TD4 on a breadboard. Here is my manual clock on a breadboard.

Here is the same clock, but instead of manual, now it runs at 1.2 Hz (approx). This is intentionally set slow in the book so it is easier to observe what is happening.

Here is my reset button. The reset has approximately a second's delay. Again, this has been intentionally made slow so it is easier to observe.

From the next post, I will start building it for real. Much soldering to be done.

Adding a ZFS pool on my home server (running debian unstable)

by Yuji Yokoo

ZFS is great. It comes with many features like built-in snapshots and spanning over multiple drives. It sounds like a good idea for my home machine which stores a lot of media data. I can have hardware redundancy by just setting up with extra drives. Fortunately, today, adding zfs support to a linux box is extremely simple. I used exact commands from and had no issue.

pools are much like partitions you can mount, which can be mirrored and striped like in raid. vdevs are raw disks that make up pools (like hdds in raids). I hear you could use a file or a partition as vdevs but the common practice is to use the entire disk.

 Okay. Let's create a pool: 


$ sudo zpool create zpool0 sdd sde
invalid vdev specification
use '-f' to override the following errors:

/dev/sdd does not contain an EFI label but it may contain partition information in the MBR.

Okay. One problem. Not sure what it means but it seems like it is because I'm missing partition information on these disks ( Using '-f' is supposed to override.

$ sudo zpool create -f zpool0 sdd sde

$ sudo zpool list
zpool0 5.44T 580K 5.44T 0% 1.00x ONLINE -

$ sudo zpool status
pool: zpool0
state: ONLINE
scan: none requested

zpool0 ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0

Success! It is automatically mounted too:

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs           19G  8.6G  8.7G  50% /
udev             10M     0   10M   0% /dev
tmpfs           789M  1.8M  787M   1% /run
/dev/sda1        19G  8.6G  8.7G  50% /
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           2.4G     0  2.4G   0% /run/shm
/dev/sda6        88G   72G   12G  87% /home
zpool0          5.4T  128K  5.4T   1% /zpool0

But I want to change the mount point, so I run this command: 

$ sudo zfs set mountpoint=/opt/zdata0 zpool0
$ df -h /opt/zdata0
Filesystem Size Used Avail Use% Mounted on
zpool0 5.4T 128K 5.4T 1% /opt/zdata0

Now I have a 5.4TB partition to store all my media files.

Reboot issues: I found that this setup will require me to run zfs mount -a every time I reboot. This is not ideal. The solution is to modify /etc/default/zfs:


# Run `zfs mount -a` during system start?
# This should be 'no' if zfs-mountall or a systemd generator is available.
ZFS_MOUNT='yes' # <- change this line from 'no' to 'yes'

Now my zfs partitions should be automatically mounted.

UPDATE: To create radiz-2, use zpool create -f zpool0 raidz2 sdd sde sdf sdg sdh

UPDATE: It's better to use disk ids you can get from /dev/disk/by-id than sdd, sde etc.

It has been years...

by Yuji Yokoo

It has been years (literally!) since I made my last post. This year, in the last part of February, I've decided I need to write more. So I'm starting with a contentless post here.

Getting started with mruby (Part 3)

by Yuji Yokoo

In the previous posts, I have got up to the point where I built mruby and ran some ruby code in 6 different ways.

Now let me continue from there and demonstrate some other ways of using mruby.

mruby on MIPS

mruby can be compiled for many platforms. I happen to have a MISP router (D-Link DIR-320) running openwrt. If you want to find out more, see

This should build openwrt and its toolchain. If you are not 100% sure your image is compatible with this version of toolchain, you should install this new image on your router.

Next, you need to build mruby for MIPS. I'll just copy the mruby directory and rename it mruby-mips:

Interesting. Building mruby depends on mrbc! An easy way to work around this is to copy your platform's mrbc to bin:

This should build mruby now. My openwrt (I think openwrt by default) has the ip address of Also, I can run "strip" to make the file smaller. Then I copy the file, ssh into the router, and run the mruby executable like this:


Cross compiling mruby programs for MIPS

You can also cross-compile the mruby-generated C code for MIPS using the openwrt toolchain. I still have the same helloworld.c and helloworld_main.c generated from previous posts:

You can compile these, copy, then run as follows:


Calling mruby from PHP with php-mruby

php-mruby ( lets you embed mruby calls within your PHP scripts:

This should build and install php-mruby. Then make a php file like this:

Now it's time to run the mruby inside php:

Great success! Now you can write mruby inside PHP!

Other interesting things (which I should look at next)

There are lots of interesting things happening with mruby right now. Some examples here:

Update (13/12/2012)

For a list of mruby-related projects, see

Also, it looks like is the correct place instead of "Sinachiku" link above.