Raspberry Pi Osborne 1 Rebuild
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 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.
No comments:
Post a Comment