2:5 Scale KENBAK-1 Personal Computer Reproduction

Make a working reproduction of the venerable KENBAK-1 with a fully integrated development environment including an Assembler and Debugger.

Similar projects worth following


If you have been following Hackaday for a while, you will have seen on numerous occasions the KENBAK-1, regarded by many as the first commercial personal computer.  Ten years ago Mark Wilson introduced KENBAK-uino, a reproduction running in emulation on an ATmega328. In 2016  posted a great writeup about John Blankenbaker KENBAK-1's creator. For a first hand account of the KENBAK-1 story you should really have a look at John Blakenbaker's own KENBAK-1 Computer site.

For a while you could purchase a full size KENBAK-1 Reproduction Kit, with a PCB, power supply, authentic metal case, 132 standard series TTL logic ICs as the CPU / process control logic (that's right no microprocessor) and two 1024 bit shift registers for memory.  Unfortunately this option is no longer available, but based on Mark Wilson's code Adwater & Stir offers a ruler sized nanoKENBAK-1, a half size µKENBAK-1 kit, and will soon be offering a full sized kit as well. In addition you can find KENBAK-1 emulators online like this one.


So with all of this rightly deserved KENBAK-1 love out there, why am I creating yet another KENBAK-1 emulator?  The flip answer might be that I want to and I can, but that's not all of it. While all of the wonderful reproductions out there emulate the original to a tee and give a true KENBAK-1 experience, and even have some addition features like built in programs, at the end of the day you are still in many cases hand translating machine instructions and keying them in via the front panel buttons one step at a time.  And when something goes wrong, while you can step through your program one instruction at a time you only have visibility into one thing at a time on the front panel display, the instruction or a memory/register address. It gets old pretty fast. 

Where I think I can add some value is to integrate the machine code Emulator with an Assembler and a Debugger.  You will still be able to fire up my KENBAK-2/5 console to key and run your programs in native mode via the front panel. In addition you will be able to open an integrated development environment, enter in a KENBAK-1 program via assembly language and run said program using the actual console.  Similarly you will be able to step through your assembly code, set break points, and observe memory and register contents as you do. 

My other motivation for this project is that I really wanted to do a deep dive on this machine. When I looked at the Programming Reference Manual I was very impressed with the machine architecture and the instruction set. I mean an Indirect Indexed addressing mode on a machine built with logic chips. So cool.  

Design Considerations

  • The console itself will be rendered at 2:5 scale (hence the name KENBAK-2/5).  This is primarily so that all of the parts will fit onto the print bed of my Prusa MK3S.
  • A built in Raspberry Pi 4 will be connected to the front panel via a 32 channel port expander. In addition to running the KENBAK-1 Emulator, the extra horse power of the Pi will be required to run the "integrated development environment" (IDE).
  • The IDE will be accessed by connecting a display, keyboard, and mouse to the console's PI 4 itself or via VNC (preferred).
  • The Emulator, Assembler, and Debugger will be written in Python.

  • We Have Blinkenlights!

    Michael Gardi2 days ago 3 comments

    With the wiring complete I wrote a small program in Python to test the lights, buttons, and switches on the front panel. To be clear this is NOT the KENBAK-2/5 emulator running a program (yet). 

    As it turns out I did have to replace one of the LEDs which wasn't working.

    The Python script communicates with the MCP23017 32 Channel I/O Expansion HAT through the Python wiringpi library. Here is the code for my test program. 

    import wiringpi as wiringpi
    from time import sleep
    # Set the base number of ic1.
    ic1_pin_base = 65
    # Pin number to code number:
    # 1 = 65, 2 = 66, 3 = 67, 4 = 68, 5 = 69, 6 = 70, 7 = 71, 8 = 72, 9 = 73, 10 = 74, 11 = 75, 12 = 76, 13 = 77, 14 = 78, 15 = 79, 16 = 80
    # Define the i2c address of ic1.
    ic1_i2c_addr = 0x24
    # Set the base number of ic2.
    ic2_pin_base = 81
    # Pin number to code number:
    # 1 = 81, 2 = 82, 3 = 83, 4 = 84, 5 = 85, 6 = 86, 7 = 87, 8 = 88, 9 = 89, 10 = 90, 11 = 91, 12 = 92, 13 = 93, 14 = 94, 15 = 95, 16 = 96
    # Define the i2c address of ic2.
    ic2_i2c_addr = 0x20
    # Initialize the wiringpi library.
    # enable ic1 on the mcp23017 hat
    # enable ic2 on the mcp23017 hat
    # Setup led pins.
    light_stop = 65
    light_store = 66
    light_set = 67
    light_clear = 68
    light_0 = 73
    light_1 = 74
    light_2 = 75
    light_3 = 76
    light_4 = 77
    light_5 = 78
    light_6 = 79
    light_7 = 80
    # Setup toggle pins.
    toggle_off = 69
    toggle_on = 70
    toggle_unl = 71
    toggle_lock = 72
    # Setup button pins
    button_stop = 81
    button_start = 82
    button_store = 83
    button_read = 84
    button_set = 85
    button_display = 86
    button_clear = 87 
    button_0 = 89
    button_1 = 90
    button_2 = 91
    button_3 = 92
    button_4 = 93
    button_5 = 94
    button_6 = 95
    button_7 = 96
    # Set the pin mode to an output for all the leds.
    # Set all the leds off to start with.
    # Set the pin mode to an input for all the switches and buttons.
    # Enable the internal pull-ups on all the inputs
    Read more »

  • Wiring

    Michael Gardi4 days ago 0 comments

    Well my port extender hat finally arrived so I got busy wiring the front panel to the Raspberry Pi via the extender.

    The port extender came with standoffs, so I used two diagonal corner holes on the Raspberry Pi to mount it to the bottom frame, and the opposite two corner holes with the standoffs to support the hat. Seems reasonably solid.

    In the following photo I'm about half done. A ground wire has been routed to all of the front panel components, the fifteen push buttons have been connected to the hat, and the twelve LEDs have a short wire with a limiting resistor attached. The resistors are 10k to keep the brightness down.

    I used female headers to connect the front panel lights and buttons to the extender. Because there wasn't a lot of head room with the top frame on, and space between the male headers on the board, I had to angle the wires as in the photo below.

    It was a little tight, and as I soldered the wires onto the the header I kept asking myself why I hadn't designed a PCB for the front panel. At the end of the day though it worked out OK. 

    The red heat shrink protects the "inline" limiting resistors for the LEDs. A few cable ties and my KENBAK-2/5 is ready to go.  

    Next step is to write the code to manage the front panel and integrate it with my Emulator.

  • Is Emulation Really the Sincerest Form of Flattery?

    Michael Gardi04/11/2021 at 19:29 0 comments

    The Emulator for my KENBAK-2/5 Reproduction simulates in software the operation of the 132 integrated circuits that made up the original KENBAK-1's hardware.  It accepts as input a 256 byte array that represents the entire block of memory that was in a KENBAK-1 and executes the instructions encoded into those bytes until a HALT instruction is encountered.  

    While an Assembler takes the symbolic representation of an instruction like LOAD A,1 and converts it into two byte codes 0x13 and 0x01, the emulator recognizes that 0x13 means load the A register with the byte that immediately follows the op code being executed (0x13) and alters the value of the A register to be a 1.

    So here is a picture of my KENBAK-2/5 Emulator loaded with the byte codes produced by running my Assembler on the Fibonacci sequence program from the previous log entry.

    On this screen we can see:

    • Left - The values of nine special memory locations in the KENBAK-1;
      A000A register.
      001B register.
      X002C register.
      PC003Program counter.
      OUT129Maps to front panel data display lamps.
      OCA130Overflow/Carry bits for A register.
      OCB131Overflow/Carry bits for B register.
      OCX132Overflow/Carry bits for C register.
      IN255Maps to the front panel data input button 
    • Middle - A hex based overview of the 256 bytes of KENBAK-1 memory.
    • Right - A more detailed view of the memory bytes in hex, digital, octal, and binary representations.

    Here is a short video of the Emulator in action.

  • A Minimal Viable Working Assembler

    Michael Gardi04/11/2021 at 15:50 0 comments

    I'm still waiting on a port extender hat for my Pi 4 so I have had a lot of time to work on the KENBAK-2/5 software. I started with the Assembler based on the outline that I posed in the previous log. It is written in Python using Tkinter for the UI with no external libraries. You can find this early version of the program in the GitHub link associated with this project.

    This stand alone Assembler component will eventually be incorporated into a simple IDE for the KENBAK-1.

    Here is a short video of the Assembler in action.

    And a screen shot of the Assembler with the Fibonacci program loaded.

    Here we can see:

    • labels and labels with offsets (+1,  +2)
    • pre-defined memory locations (OUTPUT, OCA)
    • direct and indexed addressing modes
    • constants

    With the Assembler done I wrote a number of small programs to exercise the various op codes and addressing modes. These I verified by manually checking the byte codes produced against the documentation in the KENBAK-1 Programming Reference Manual. This is pretty tedious work so I was anxious to get on with the next step, an Emulator.

  • Writing an Assembler

    Michael Gardi04/06/2021 at 02:06 0 comments

    The KENBAK-1 was intended for the education market. As a result the documentation is excellent. The Programming Reference Manual has all of the information necessary to construct an Assembler for the KENBAK-1 computer:

    • Memory Structure and Addressing - The KENBAK-1 is an 8-bit computer with  memory of 256 bytes.
    • Special Memory Locations - Nine memory locations are used for special purposes.
      • A Register - Primary register for arithmetic unit. (000)
      • B Register - Secondary register for arithmetic unit. (001)
      • X Register - Used for Indexed address mode and arithmetic. (002)
      • P Register - Program instruction address. (003)
      • Output Register - Maps to the front panel lights. (128)
      • Overflow and Carry for the A Register. (129)
      • Overflow and Carry for the B Register. (130)
      • Overflow and Carry for the X Register. (131)
      • Input Register - Maps to the front panel data buttons. (255)
    • Number Representations - Including unsigned and signed 8-bit integers and signed fractions.
    • Addressing Modes - There are five addressing modes that affect the meaning the second word of an instruction:
      • Immediate - is the operand.
      • Memory - is the address of the operand. 
      • Indirect - is the address of the address of the operand.
      • Indexed - the contents are added to the X register to form the operand address.
      • Indexed Indirect - the contents are used as an address pointer to a second address to which the X register is added to form the operand address.
    • Instruction Descriptions - Includes a complete description of the operation of each one and two byte instruction and the bits used for each OpCode variant (addressing modes, register selection, etc.)

    The Symbolic Representation of Instructions section of the manual gives some guidance as to the abbreviations to be used and the layout for "written" symbolic KENBAK-1 instructions including how to represent the various addressing modes. For the most part I followed these guidelines. I couldn't however bring myself to use NOOP for the no op instruction (I used NOP) and I felt that +X worked better to represent Indexed addressing mode as opposed to ,X. I had a lot of fun trying to come up with a consistent overall look for the instructions. 

    So in the end I came up with the following document which I feel represents everything I need to provide in a "minimal viable assembler" (MVA) for my KENBAK-2/5 machine.

    Assembler Syntax
    add    [A|B|X],[constant|address]            ;[I|M|(M)|M+X|(M)+X]
    sub    [A|B|X],[constant|address]            ;
    load   [A|B|X],[constant|address]            ;
    store  [A|B|X],[constant|address]            ;
    and    [A],[constant|address]                ;
    or     [A],[constant|address]                ;
    lneg   [A],[constant|address]                ;
    jmp    [A|B|X],[NE|EQ|LT|GE|GT|GLE],address  ;[M|(M)]
    jmk    [A|B|X],[NE|EQ|LT|GE|GT|GLE],address  ;
    skp    [7|6|5|5|4|3|2|1|0],[0|1],address     ;[M]
    set    [7|6|5|5|4|3|2|1|0],[0|1],address     ;
    sft    [A|B],[L|R],[1|2|3|4]
    rot    [A|B],[L|R],[1|2|3|4]
    org    constant                              ;[I]
           org    constant                       ;[I] 
    label  [blank|instruction|constant]          ;[I] 
           constant                              ;[I] 
    The org directive can appear anywhere to set the starting instruction address
    for all instructions that follow. If a constant is not present address 4 is 
    If the OpCode position has an Integer Constant, then the value of that constant
    is placed at the current address, and the program counter is advanced by one. 
    * Any text appearing after a semi-colon (;) on a line will be considered a 
      comment and be ignored.
    * All OpCodes, operands, and labels are NOT case sensitive.
    * A line of assembly code consists...
    Read more »

  • Making the Console

    Michael Gardi04/05/2021 at 17:56 0 comments

    The KENBAL-2/5 console has a 3D printed frame and uses panel mount components. At 40% the size of the original a few compromises had to be made. For one, the great keyboard style push buttons on the front panel of John Blakenbaker's machine proved impossible to replicate. In fact the button positions had to be stretched out horizontally a bit on my reproduction to accommodate the small panel mount push buttons that I did find.  Similarly no nice sockets for the panel lamps, just rear mounted 3 mm LEDs.

    The advantage of the small size is that the pieces will fit on a fairly large selection of 3D printers out there. The shape of the case is a pretty close match to the original as far as I can tell. It is printed in five parts. The bottom has mounting pegs for this project's Raspberry Pi "engine" and cutouts for cabling. 

    Nothing special about top piece. Notice the groove in both the top and bottom pieces used to hold the front panel in place.

    The front panel has holes to hold the buttons, switches, and lights. Because of the small size of the reproduction I was not able to just 3D print the labels directly on the panel as I have in the past with other projects. Instead I saved a DXF file with the panel outline and hole positions from my Fusion 360 model and brought that into Inkscape where I added the labels. I printed the resulting SVG file onto a clear overhead sheet which I laminated to protect the printing and add rigidity to the overlay.  I cut the overlay out along the outline and punched the button and switch holes with a standard hand held 1/4" paper punch. The panel lights are recessed behind the overlay so do not require holes.

    I could not use the nuts that came with the panel mount buttons and switches because they would not fit at this scale. Instead I sized the holes in the front panel so that the components could be screwed in from the back self threading as they did. The LEDs are just friction fit.

    The overlay with the labels will just fit over the buttons and switches with a little finessing. 

    The front panel fits into the grooves cut into the top and bottom pieces.

    Join the top and bottom pieces with the slotted side pieces.

    And that's it for the console.

    I'm waiting for the port extender hat. When it arrives I'll be wiring the KENBAK-2/5 up. In the mean time I'll be working on the software side.

View all 6 project logs

Enjoy this project?



Cees Meijer wrote 04/07/2021 at 14:18 point

As a retro computer enthousiast I certainly heard of the KENBAK. And also thought about making a replica like this. Yours looks realy great !. Do you intend to publish the 3D design ?

  Are you sure? yes | no

Michael Gardi wrote 04/07/2021 at 15:34 point

Hello. I just posted the design files for the case to GitHub and added a link to them in this project. The software is still a few weeks away.  Thanks for your interest.

  Are you sure? yes | no

Dan Maloney wrote 04/06/2021 at 17:19 point

And here I was thinking I knew all the cool computers from the first wave of the hobbyist PC revolution. But I'd never heard of this one. Nice looking machine -- I'll have to dig into it a little more.

Looking forward to more details on the repro!

  Are you sure? yes | no

Michael Gardi wrote 04/06/2021 at 18:26 point

This one kinda slipped under my radar too. I'm enjoying my deep dive into the inner workings of the KENBAK-1. An interesting piece of personal computing history for sure.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates