Introduction: Raspberry Pi Osborne 1 Rebuild

About: Making Stuff since the 80's

Hello

In this inscrutable I'm going to show how to create a working Osborne 1 Replicae using an raspberry Pi and Arduino some hot glue and little bit of wire and so solder

My motivation behind this is a passion for vintage computers and a little bit of mashup of new and old technology is always fun. And its also good way of experiencing how old computer worked like in the early days of computer but without having to deal with the old unreliable slow hardware.

A short video of the Osborne Pi Booting

Step 1: What You Need

Step 2: Setting Up the Software and Confining the PI

You will need a working copy of raspian install on your raspberry pi. If you need help getting an image on you pi click here

Once the pi you need to download the CP/M Emulator software

Open a terminal and Download the software

    
 $ git clone  https://github.com/jhallen/cpm.git

Then Compile the software

    
 $ cd cpm
 $ sudo make
    

Run the software

    
 $ ./cpm
    

You should get an a: promtto exit type bye

The software which we downloaded is a cp/m emulator you can read more about here

I downloaded some software from www.retroarchive.org/cpm/ and then copied into the cpm directory.

We need to set the PI to boot automatically in to the cpm emulator

Edit the bash file

    
 $ sudo nano /home/pi/.bashrc
    

Add these to lines to the bottom of the file

    
echo running at boot
sudo cpm/cpm
    

Next Up is the screen it requires a custom display mode due to the resolution been non-standard

Edit the config.ini

    
sudo nano /boot/config.ini
    

Add these lines to the bottom for the file

  
max_usb_current=1
hdmi_group=2
hdmi_mode=87
hdmi_cvt 800 480 60 6 0 0 0
hdmi_drive=1  

    

Also I edited the same file and changed the overscan so I got a 4:3 aspect ratio

  
overscan_left=32
overscan_right=25


    

Step 3: The Keyboard !!!

A big part of this project was getting the keyboard to work as a USB Hid device. To do this I have connected the keyboard up to a Arduino micro.

You can download the code from here.

I have taken and modified the code used to make the a ZX81 USB keyboard.

I add an 8 x 8 matrix to take account for all the extra keys. The code works by when a key is pressed it completes the circuit across the row and column, which it then looks up in the matrix table. I got the matrix table from oldpinouts

    
#include <Keyboard.h>

// ZX81 USB Keyboard for Leonardo
// (c) Dave Curran
// 2013-04-27

// Modified with Function keys by Tony Smith
// 2014-02-15

// Modified for use with Osbone Computer Keyboard by Keith
// Added 8 by 8 matrix
// Changed DEBOUNCE value
// 2018-04-02
// The Numbers are Special ASCII characters<br>
#define NUM_ROWS 8
#define NUM_COLS 8

// Keymap for normal use
byte keyMap[NUM_ROWS][NUM_COLS] = {
   //0   1   2   3   4   5   6   7
 {177,179,128,' ',129,176,178,'['}, //A0
 {' ',' ',',',193,' ',' ',' ',' '}, // A7
 {'1','2','3','4','5','6','7','8'}, //A1
 {'q','w','e','r','t','y','u','i'}, //A2
 {'a','s','d','f','g','h','j','k'}, //A3
 {'z','x','c','v','b','n','m',','}, //A4
 {215,217,'-','/',';','|','l','='}, //A6
 {218,216,'0',' ','.','p','o','9'}, //A5 
};

// Keymap if Shift is pressed
byte keyMapShifted[NUM_ROWS][NUM_COLS] = {
   //0   1   2   3   4   5   6   7
 {177,179,128,' ',129,176,212,'['}, //A0
 {' ',' ',',',193,' ',' ',' ',' '}, // A7
 {'!','@','#',','%','^','&','*'}, //A1<br> {'Q','W','E','R','R','Y','U','I'}, //A2
 {'A','S','D','F','G','H','J','K'}, //A3
 {'Z','X','C','V','B','N','M','<'}, //A4
 {215,217,'_','?',':','"','L','+'}, //A6
 {218,216,')',' ','>','P','O','('}, //A5 
};

// keymap if Shift is pressed plus New Line
// *Next* key read should be from this table
byte keyMapAlt[NUM_ROWS][NUM_COLS] = {
   //0   1   2   3   4   5   6   7
 {177,179,128,' ',129,176,212,'['}, //A0
 {' ',' ',',',193,' ',' ',' ',' '}, // A7
 {'!','@','#',','%','^','&','*'}, //A1
 {'Q','W','E','R','R','Y','U','I'}, //A2
 {'A','S','D','F','G','H','J','K'}, //A3
 {'Z','X','C','V','B','N','M','<'}, //A4
 {215,217,'_','?',':','"','L','+'}, //A6
 {218,216,')',' ','>','P','O','('}, //A5 
};

// Global variables
int debounceCount[NUM_ROWS][NUM_COLS];
int altKeyFlag;
int ctrlKeyFlag;

// Define the row and column pins
byte colPins[NUM_COLS] = {8, 9, 10, 11, 12, 13, A0, A1};
byte rowPins[NUM_ROWS] = {A2, 1, 2, 3, 4, 5, 6, 7};

// Where is the Shift key
#define SHIFT_COL 4
#define SHIFT_ROW 0

// How many times does a key need to register as pressed?
#define DEBOUNCE_VALUE 100
#define REPEAT_DELAY 300

void setup() {
  // set all pins as inputs and activate pullups
  for (byte c = 0 ; c < NUM_COLS ; c++) {
    pinMode(colPins[c], INPUT);
    digitalWrite(colPins[c], HIGH);

    // Clear debounce counts
    for (byte r = 0 ; r < NUM_ROWS ; r++) {
      debounceCount[r][c] = 0;
    }
  }

  // Set all pins as inputs
  for (byte r = 0 ; r < NUM_ROWS ; r++) {
    pinMode(rowPins[r], INPUT);
  }

  // Zero Function modifier flag
  altKeyFlag = 0;
  ctrlKeyFlag = 0;

  // Initialize control over the keyboard
  // This is an Arduino Leonardo routine
  Keyboard.begin();
}

void loop() {
  // Check for Shift
  bool shifted = false;
  bool keyPressed = false;
  
  pinMode(rowPins[SHIFT_ROW], OUTPUT);

  if (digitalRead(colPins[SHIFT_COL]) == LOW) {
    shifted = true;
  }

  if (shifted == true && altKeyFlag == 255) {
    // NOP in order to prevent Function selection from auto-repeating
  } else {
    pinMode(rowPins[SHIFT_ROW], INPUT);

    // For each row
    for (byte r = 0 ; r < NUM_ROWS ; r++) {
      // Turn the row on
      pinMode(rowPins[r], OUTPUT);
      digitalWrite(rowPins[r], LOW);

      for (byte c = 0 ; c < NUM_COLS ; c++) {
        if (digitalRead(colPins[c]) == LOW) {
          // Increase the debounce count
          debounceCount[r][c]++;

          // Has the switch been pressed continually for long enough?
          int count = debounceCount[r][c];
          if (count == DEBOUNCE_VALUE) {
            // First press
            keyPressed = true;          
            pressKey(r, c, shifted);
          } else if (count > DEBOUNCE_VALUE) {
            // Check for repeats
            count -= DEBOUNCE_VALUE;
            if (count % REPEAT_DELAY == 0) {
              // Send repeat press
              keyPressed = true;          
              pressKey(r, c, shifted);
            }  
          }
        } else {
          // No key pressed, so reset debounce count
          debounceCount[r][c] = 0;
        }
      }

      // Turn the row back off
      pinMode(rowPins[r], INPUT);
    }

    digitalWrite(rowPins[SHIFT_ROW], LOW);
  }
}

// Send the keypress
void pressKey(byte r, byte c, bool shifted) {  
  byte key = shifted ? keyMapShifted[r][c] : keyMap[r][c];

  if (altKeyFlag == 255) {
    // Get the Alt key pressed after Function has been selected
    key = keyMapAlt[r][c];
    altKeyFlag = 0;
  }

  if (key == KEY_F5) {
    // If the Function key pressed (Shift + New Line)
    altKeyFlag = 255;
    key = 0;
    debounceCount[r][c] = 0;
  }
  
  if (key == KEY_F6) {
    ctrlKeyFlag = 255;
    key = 0;
    debounceCount[r][c] = 0;
  }

  if (key > 0) {
    // Send the key
    if (ctrlKeyFlag == 255) {
      ctrlKeyFlag = 0;
      Keyboard.press(KEY_LEFT_CTRL);
      Keyboard.press(key);
      delay(100);
      Keyboard.releaseAll();
      return;
    }
    
    Keyboard.write(key);
  }
}

    

I made a 20 pin connector out of some perf board and some pin headers. Once done I solder some jumper wires and connected them to the Arduino. I then held it all in place with lots of hot glue. You've got to love hot glue.

Step 4: Putting It Together

The final step of the process is to fix all the comments to the front of the Osborne computer.

This is a simple job of hot glueing all the parts in place.

I then 3D printed out some planking plates to cover up all the ports which aren't been used. You could use some card it doesn't need to be 3D printed. I added an usb extension cable to the PI so I could use a mouse or copy files using a memory stick.

Step 5: Finished

So not much left to do but play a little Zork on the 1980's replicate computer

I would like to add an external HDMI port so it can be on a bigger screen.

It would also be nice to add battery to make this a true portable computer.

Microcontroller Contest

Participated in the
Microcontroller Contest