NEC PC-8801 (Davey's first blue alps experience)

User avatar
Blaise170
ALPS キーボード

25 Jun 2018, 03:40

Why didn't you just get a breadboard and solder it into that? Seems like it would have been a lot easier and much more secure. Kind of like the way Hasu does on his adapters.

Image

User avatar
Sangdrax

25 Jun 2018, 04:46

snacksthecat wrote: The explanation of the protocol sounds simple but I'm stuck at step #0

WHAT DOES IT ALL MEAN?!?!
That it's not a protocol at all but rather the computer itself is the controller.

User avatar
snacksthecat
✶✶✶✶

25 Jun 2018, 13:45

Blaise170 wrote: Why didn't you just get a breadboard and solder it into that? Seems like it would have been a lot easier and much more secure. Kind of like the way Hasu does on his adapters.

Image
Ooooh that would have worked much better. I’ll remeber this for next time (I’m a total electronics novice).

User avatar
snacksthecat
✶✶✶✶

27 Jul 2018, 04:06

Here's my lame attempt at mapping things out, in terms of what connects to what.

Image

Certainly seems to match the explanation that I was reading on that one site
What this means in practice is that the PC88 itself does the key reading. The keyboard connector has 13 pins (14 if you count the ground sleeve), and in order to read a key, the computer triggers four of those pins. A multiplexer on the keyboard uses those four lines to activate the appropriate row on the keyboard matrix, and eight lines are triggered in response to tell the computer which keys on that row are pressed.
https://www.leadedsolder.com/2018/04/14 ... llies.html

Unfortunately I'm not sure what I should do with this information. Any suggestions on where to start?

User avatar
snacksthecat
✶✶✶✶

28 Jul 2018, 00:47

Please help! I want to be a dignified keyboard conductor and have a mini virtual ballerina like this guy

Image

User avatar
Blaise170
ALPS キーボード

28 Jul 2018, 01:40

That's sick. Never saw that brochure before.

User avatar
snacksthecat
✶✶✶✶

31 Jul 2018, 23:32

I've been thinking about this a lot and I may finally have my head around it. I think it might help me cement that further if I write it down. Here's how I currently think the keyboard reading works:
  • The computer (or microcontroller) activates some pattern of the first 4 pins to query a row.
  • The IC on the keyboard translates this pattern and in turn activates the selected row on the keyboard.
  • The computer (or micro controller) reads the 8 remaining pins to determine which keys in the row are pressed.
Here's the pinout for reference:

Code: Select all

    0 Gnd
    0 Vcc

    0 \
    0 | Signal pins
    0 | 
    0 /

    0 \
    0 |
    0 |
    0 | Row pins
    0 |
    0 |
    0 |
	 0 /

User avatar
Wingklip

01 Aug 2018, 13:24

+interest. Would also like to figure how to convert mine. Found one resting in a hard off at chiba, the other one I didn't buy because even though the alps were blue they felt like rubber domes

User avatar
snacksthecat
✶✶✶✶

02 Aug 2018, 00:07

I confirmed with a quick and dirty arduino sketch that this is most likely how the keyboard reading works.

My sketch pulls one of the signal pins low then reads each of the remaining 8 pins. If you press a key on the keyboard that's in the row corresponding to the signal pin that was pulled low, the sketch will output the matching column number.

The next step would be to figure out:
  1. What are all of the rows (this should be traceable visually or with a multimeter)
  2. What what patters of the 4 signal lines correspond to each of the rows (i.e. if I want to query row #1, which signal pins should I activate?)
This is a bit outside my wheelhouse but I feel like I'm learning a lot and having fun :P

Edit: Again that leadedsolder blogger comes to my rescue. He posted the keymap in memory and it seems to match the patterns I'm seeing. Hopefully this makes the trial and error process a whole lot easier because I have a map to go off of.
Image
https://www.leadedsolder.com/2018/04/14 ... llies.html

User avatar
snacksthecat
✶✶✶✶

02 Aug 2018, 02:05

Here's what the patters are looking like. My keyboard doesn't have the bottom two rows of keys but you could probably figure them out easily through the process of elimination.

Everything matched up to that memory map exactly with a couple of exceptions where a keypress didn't generate any output. I'm assuming for now that those are dead switches but that should be easy enough to determine.

Image

User avatar
snacksthecat
✶✶✶✶

03 Aug 2018, 01:46

Update: I was able to get it converted last night. If there's any interest, I can post the full details and source code here.

User avatar
snacksthecat
✶✶✶✶

03 Aug 2018, 21:47

As promised, here are the details on how to build a converter for this keyboard. I'm a novice when it comes to arduino/teensy programming but everything seems to work. It even supports NKRO! I'll try to make the instructions as clear as possible but please do feel free to ask a question. The keymap I used makes sense to me (for now) but it is modifiable quite easily if you'd like to recompile the code.

Pinout
Spoiler:
I'm using the arduino pin numbers so if you're using a teensy then this diagram should help you.
Image

Here are the pins on the board:
Image

And the corresponding pins on the cable and plug
Image

Image
Code
Spoiler:
Here is the code for the converter. I'm using the arduino keyboard library so if you'd like to switch around the keymap, you can use this page to find all the keycodes. To compile the sketch in the arduino IDE, make sure you've set the USB type to keyboard by going to: Tools > Usb Type > Keyboard + Mouse + Joystick.

Code: Select all

/* Copyright (C) 2018 David M. Bednarski
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
ypconst int keyCount = 92;
const long keyMap[12][8] = {
  { KEYPAD_0,       KEYPAD_1,      KEYPAD_2,       KEYPAD_3,      KEYPAD_4,        KEYPAD_5,         KEYPAD_6,          KEYPAD_7         },
  { KEYPAD_8,       KEYPAD_9,      KEYPAD_ASTERIX, KEYPAD_PLUS,   KEYPAD_ENTER,    KEY_COMMA,        KEYPAD_PERIOD,     KEYPAD_ENTER     },
  { KEY_LEFT_BRACE, KEY_A,         KEY_B,          KEY_C,         KEY_D,           KEY_E,            KEY_F,             KEY_G            },
  { KEY_H,          KEY_I,         KEY_J,          KEY_K,         KEY_L,           KEY_M,            KEY_N,             KEY_O            },
  { KEY_P,          KEY_Q,         KEY_R,          KEY_S,         KEY_T,           KEY_U,            KEY_V,             KEY_W            },
  { KEY_X,          KEY_Y,         KEY_Z,          KEY_TILDE,     KEY_SLASH,       KEY_SLASH,        KEY_EQUAL,         KEY_MINUS        },
  { KEY_0,          KEY_1,         KEY_2,          KEY_3,         KEY_4,           KEY_5,            KEY_6,             KEY_7            },
  { KEY_8,          KEY_9,         KEY_QUOTE,      KEY_SEMICOLON, KEY_COMMA,       KEY_PERIOD,       KEY_SLASH,         KEY_BACKSLASH    },
  { KEY_DELETE,     KEY_UP,        KEY_RIGHT,      KEY_BACKSPACE, MODIFIERKEY_ALT, MODIFIERKEY_CTRL, MODIFIERKEY_SHIFT, MODIFIERKEY_CTRL },
  { KEY_ESC,        KEY_F1,        KEY_F2,         KEY_F3,        KEY_F4,          KEY_F5,           KEY_SPACE,         KEY_ESC          },
  { KEY_TAB,        KEY_DOWN,      KEY_LEFT,       KEY_INSERT,    KEY_ESC,         KEYPAD_MINUS,     KEYPAD_SLASH,      KEY_CAPS_LOCK    },
  { KEY_PAGE_UP,    KEY_PAGE_DOWN, 0,              0,             0,               0,                0,                 0                }
};

long keysHeld[keyCount];
long keysPressed[keyCount];

void setup() {
  // put your setup code here, to run once:

  // Signal pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  
  // Input pins
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);

  Serial.begin(115200);
  Serial.println("hidave");
}

void addHeldKey(long key) {
    for(int i = 0; i < keyCount; i++) {
      
    if(keysHeld[i] == 0) {
      keysHeld[i] = key;
      Keyboard.release(key);
      break;
    }
  } 
}

void removeHeldKey(long key) {
    for(int i = 0; i < keyCount; i++) {
      if(keysHeld[i] == key) {
        keysHeld[i] = 0;
        break;
      }
  }
}

void readInputPins(int row) {
  int col = 0;

  // For each column pin
  for(int i = 4; i < 12; i++) {

    // If the key is pressed
    if(digitalRead(i) == LOW) {
      long key = keyMap[row][col]; 

      // Place it in an empty slot
      for(int j = 0; j < keyCount; j++) {    
        if(keysPressed[j] == 0) {
          keysPressed[j] = key;
          break;
        }
      }
    }
    col++;
  }
}

void queryRow(int row) {
    // Pin 0
    if(row == 0 or 
       row == 1 or 
       row == 2 or 
       row == 3 or 
       row == 4 or 
       row == 5 or 
       row == 6 or 
       row == 7) {
      pinMode(0, OUTPUT);
      digitalWrite(0, LOW);
    }

    // Pin 1
    if(row == 0 or 
       row == 1 or 
       row == 2 or 
       row == 3 or 
       row == 8 or 
       row == 9 or 
       row == 10 or 
       row == 11) {
      pinMode(1, OUTPUT);
      digitalWrite(1, LOW);
    }

    // Pin 2
    if(row == 0 or 
       row == 1 or 
       row == 4 or 
       row == 5 or 
       row == 8 or 
       row == 9) {
      pinMode(2, OUTPUT);
      digitalWrite(2, LOW);
    }

    // Pin 3
    if(row == 0 or 
       row == 2 or 
       row == 4 or 
       row == 6 or 
       row == 8 or
       row == 10) {
      pinMode(3, OUTPUT);
      digitalWrite(3, LOW);
    }

    readInputPins(row);

    // Revert pin to input
    pinMode(0, INPUT_PULLUP);   
    pinMode(1, INPUT_PULLUP);  
    pinMode(2, INPUT_PULLUP); 
    pinMode(3, INPUT_PULLUP);
}

void updateKeysPressed() {
  for(int i = 0; i < 12; i++) {
    queryRow(i);
  }
}

void clearKeysPressed() {
  for(int i = 0; i < keyCount; i++) {
    keysPressed[i] = 0;
  }
}

void updateKeysHeld() {
  long key;

  for(int i = 0; i < keyCount; i++) {
    key = keysPressed[i];

    if(key != 0) {
      if(checkForHeldKey(key) == false) {
        Serial.println(key);
        addHeldKey(key);
        Keyboard.press(key);
      }
    }
  }

  for(int i = 0; i < keyCount; i++) {
    key = keysHeld[i];

    if(key != 0) {
      if(checkForReleasedKey(key) == true) {
        removeHeldKey(key);
        Keyboard.release(key);
      }
    }
    
  }
}

bool checkForHeldKey(long key) {
  bool result = false;
  
  for(int i = 0; i < keyCount; i++) {
    if(keysHeld[i] == key and key != 0) {
      result = true;
      break;
    }
  }

  return result;
}

bool checkForReleasedKey(long key) {
  bool result = true;

  for(int i = 0; i < keyCount; i++) {
    if(keysPressed[i] == key and key != 0) {
      result = false;
      break;
    }
  }
  
  return result;
}

void loop() {
  // Clear out the old keys
  clearKeysPressed();
  
  // Load up the currently pressed keys
  updateKeysPressed();

  updateKeysHeld();

    
}
Flashing
Spoiler:
If you're building from the source code, use the arduino IDE to compile and upload to the microcontroller.
If you're flashing the compiled binaries, you can use the teensy uploader to AVR dude to flash the microcontroller.
I think there's already a lot of instructions around both of those tools so I won't include that in this post.
I'm interested to see how this works for others. Please let me know :)
Attachments
pc88.zip
(7.28 KiB) Downloaded 27 times

User avatar
Blaise170
ALPS キーボード

06 Aug 2018, 15:12

Nice! This is the first true conversion with source that I'm aware of. Next time I get some PC88s in stock, I'll have to give it a go.

User avatar
barbeque

07 Aug 2018, 02:47

Hey! I am the guy behind leadedsolder.com. I am so glad you made good use of it, and even more glad you didn't gut an rare (and getting rarer) keyboard just for the switches :)

I did eventually pick up my own mkIISR keyboard for my mkII; it was way more money than I wanted to spend, and is dirty and battered (and stinky!) but it works:

Image

If I made any mistakes, please let me know and I can correct the post - the map was kind of a guess based on the keymap structure in a PC88 emulator.

I also got the machine working as of this week, so I can do more testing if need be: Part 1 - setup, Part 2 - building a video cable.

Your adapter looks awesome. I am really tempted to build one now.

Blaise170, if you end up with any extra keycaps for those keyboards I would like to make mine complete one day. And if you end up with a colour video cable for one, that would also save me from having to solder an 8-pin DIN in the immediate future.

User avatar
snacksthecat
✶✶✶✶

09 Aug 2018, 20:25

barbeque wrote: Hey! I am the guy behind leadedsolder.com. I am so glad you made good use of it, and even more glad you didn't gut an rare (and getting rarer) keyboard just for the switches :)

I did eventually pick up my own mkIISR keyboard for my mkII; it was way more money than I wanted to spend, and is dirty and battered (and stinky!) but it works:

Image

If I made any mistakes, please let me know and I can correct the post - the map was kind of a guess based on the keymap structure in a PC88 emulator.

I also got the machine working as of this week, so I can do more testing if need be: Part 1 - setup, Part 2 - building a video cable.

Your adapter looks awesome. I am really tempted to build one now.

Blaise170, if you end up with any extra keycaps for those keyboards I would like to make mine complete one day. And if you end up with a colour video cable for one, that would also save me from having to solder an 8-pin DIN in the immediate future.
So glad you popped in. You nailed all of your descriptions perfectly and your post was a huge help (pretty remarkable considering you were doing it blind. I'm glad you were able to get your hands on a board. It may be dirty but it should clean up very nicely!

User avatar
Wingklip

25 Aug 2018, 10:03

aaaahhhh? Arduinos are coded in C?

User avatar
Blaise170
ALPS キーボード

25 Aug 2018, 13:59

Typically yes.

5syublackbird

29 Dec 2018, 18:04

:D Finally created an account to drop an inquiry, also went out of the way to purchase a few PC-8801s to try replicating a converter. The following post is a bit long winded so I apologize in advance.

I bought 3 Arduino micro clones from Aliexpress https://www.aliexpress.com/item/1pcs-TE ... 4c4dOezwJi before realizing that they lacked a "pin 11".

As a complete Electronics and Arduino noob, I used Arduino builder to forcefully flash the Hex file onto 2 Arduinos (which I may have bricked, seeing as their com ports don't appear in device manager anymore). This was also after I tried to upload the code via the Arduino IDE (but that didn't work because of errors regarding 'ypconst' being undefined).

Would you be able to disclose which particular Arduino you used or suggest a cheaper alternative that would be able to perform a similar function?

If it isn't too much of an ask, would you also be able to document in further depth or make a video on making a converter?

Thanks very much for reading this :P

(edit)
Felt it would have been too greedy if I made such a request for help without contributing in anyway. I think all of these except the Arduino might help get others right on track towards building your own converter

Ingredients/components list
- breadboard - arduino (clone) - male to female jumpers
- Female 13 pin din socket - Micro-USB cable

Post Reply

Return to “Workshop”