Friday, October 23, 2015

Downgrading Windows 8.1 Enterprise to Windows 8.1 Professional with a Professional N ISO

If you want to downgrade Windows 8.1 Enterprise to take advantage of the free Windows 10 upgrade then the following sources explain how to do this:

http://superuser.com/questions/479292/downgrading-windows-8-from-enterprise-to-pro
http://www.systemcenterdudes.com/change-windows-edition-from-enterprise-to-professional/

This will work if you have the Professional installation media, however if you want to do this with a Professional N ISO then there are two minor changes:

  • Change ProductName to Windows 8.1 ProfessionalN
  • Change EditionID to ProfessionalN
And then you'll be good to go. Without the 'N' addition you will not get the option to Keep Windows settings, personal files, and apps. It took a few iterations to figure this out so I hope this saves someone some time.

-(e)

Tuesday, May 5, 2015

Recapping a Sega Game Gear

I got a couple of Sega Game Gears in a auction a while back, sold as not working. This is a fairly common experience as the GG's have terrible caps which tend to leak and go bad. Luckily the fix is a fairly straight forward recapping and then you should be good to go.

I started on this last night, here are a couple of pic for reference for anyone else that wants to take a shot at this. I'll update with more posts as I go.

First off, decapping and cleaning the audio board.

So this is what it looks like:
You can see all the gunk from the leaking caps around the coil.

More horrible leaked electrolyte on the bottom of the board
My process is to snip the caps in half with a very sharp set of clippers making sure that I don't apply pressure to the solder joints.

The target cap is the little guy in the bottom left

Snipped in half

Start by snipping the cap in half. These things stink like bad fish :( nasty...
Once you have half of the cap off you should be able to gently remove the bottom half leaving the two legs exposed.

Most of the cap removed
After that you can gently pry off the base plastic of the cap and then fairly easily de-solder the legs. Use some flux and add solder initially to get the legs off and to get through any build up of electrolyte residue.

Board after de-soldering all the caps

Finish off with a good circuit board cleaning spray or as close to 100% isopropol alcohol as you can get and it comes up fairly nicely:

De-soldered and cleaned

-(e)

Monday, March 16, 2015

Building the Tapuino R2

Hi,

The Tapuino has gone through several iterations, this post is a revisit of the build instructions containing these updates.

DISCLAIMER: If you build this and it blows up your C64, sets your house on fire, kidnaps your dog or any other negative occurrence, I take no responsibility for this or accept no liability whatsoever. That said, I will do my best to help troubleshoot any builds (I do take responsibility for all positive occurrences ;)).

I would highly suggest that you read this entire post at least once before building the Tapuino!

Note: code and hardware design files can be found on my GitHub at: https://github.com/sweetlilmre/tapuino

So lets get started. Firstly a bill of materials:

Major components:
  • Arduino Nano V3
  • 16x2 LCD Display with I2C backpack
  • SD Card module with built-in level conversion
  • 40 wire Dupont female-female 'ribbon'
I got all of this from eBay. Here is an example shopping list:


Additional components:
  • Piece of vero board. The one I got was 100mm wide x 200mm long. This is also known as strip board and must be the kind with strips of copper (as opposed to individual 'cells')
  • 32 pin (16x2) WIDE dip socket (this is what the Nano will plug into) or 2x15 female headers
  • 6 pin (3x2) dip socket (for the opto-coupler)
  • A strip of male pin headers
  • A strip of male right-angle pin headers
  • 2 strips of female pin headers (sockets)
  • 1x 430 Ohm resistor
  • 4x Tactile switches (6x6)
  • 1x 4N25 Opto-coupler
  • Some jumper wire (I use single core wire from a piece of telephone cable)
Here are examples of the headers:

Here is a schematic of the board in Fritzing format:
Tapuino V2 schematic


So lets build the main board first. You'll want to put it together like this:
Top view of the main board


Note the minimum dimensions of the board: 29x17. You may wish to make the board larger to allow for mounting holes.

Before you assemble:

The Nano has 2x15 pins and the socket is 2x16 so if you use the socket make sure the extra pins are on the right (in the diagram above after the D12 and D13 pins), or use 2x15 pin female headers.

R1 = 430 Ohm
Green blocks = straight header pins.
Grey blocks = female headers

Break the header pins into appropriate size groups:
2x3 pins
1x6 pins
1x4 pins
and cut the female pin headers to size (mine were 40 pin, so cut down to 8 pins):

Bottom view of the main board


The lighter yellow bits are where the vero board has been cut. It is essential that you check that these tracks are cut properly. Use a multimeter to test for continuity between the tracks once cut. To cut the tracks on my prototype I used a small sharp drill bit that was luckily a perfect fit.
Please take note of the cut track between the two pins of R1 (under the resistor).


I would suggest that you solder in this order:
  1. 32 pin wide socket (or 2x15 pin female headers)
  2. 6 pin dip
  3. 2x3 pin header group next to the 6 pin dip
  4. Remaining pin headers
  5. Jumper wires

Feel free to extend the pin headers to access additional pins on the Nano if you like, I just wanted to keep it simple for wire-up later and expose only the pins necessary.

Next up is the button board, this is the much simpler V2 button board that uses internal pullups on the Nano and so doesn't need any resistors:
Top view of the button board


Note the minimum dimensions of the board: 20 x 13. You may wish to make the board larger to allow for mounting holes.

Green pin headers are right angle.The pinouts of the green pin headers, left to right are as follows: GND, BTN1, BTN2, BTN3, BTN4

Bottom view of the button board

Take careful note of the track to cut: on the 4th track (from the left) to isolate button 3 from button 1
Also note that the jumper wires for the ground lines are soldered through to multiple points. I achieved this by cutting the wires into individual sections:
  • ground line (top most line) there are 4 jumper wires of 4, 6, 6, 6 tracks in length.

Now lets install the components and connect it all up.
Firstly install the 4N25 opto-coupler into the 6 pin socket, noting where pin 1 is according to the vero board schematic. Here is a picture with the correct orientation:

Installing the 4N25 opto-coupler


Note the small dot on the chip, this indicates pin 1. The chip should be oriented such that pin 1 connects through to the 440 Ohm resistor (R1).

Next the Nano:

Installing the Nano

As discussed above, the Nano has 2x15 pins and the socket 2x16 pins. If you chose to use the 32 pin socket, care must be taken to place the Nano correctly. The Nano must be aligned so that the empty socket pins are on the right most pins of the socket as per the image above i.e. the Nano is mounted as close as possible to the opto-coupler.

If you trace out the circuit you will observe that the 2x3 pin headers between the opto and the Nano expose a ground and power rail (left is GND, right is PWR). You will use these rails to provide power to the LCD, SD Card and Button breakout boards.

Connect according to the legend in the main board image, here is a guide:

LCD:
  • Power and Ground go to the rails described above
  • Nano A5 goes to SCL
  • Nano A4 goes to SDA
SD Card:
  • Power and Ground go to the rails described above
  • Nano D13 goes to SCK
  • Nano D12 goes to MISO
  • Nano D11 goes to MOSI
  • Nano D10 goes to SS
Button Board:
  • Ground go to the rail described above
  • Nano A3 goes to BTN1
  • Nano A2 goes to BTN2
  • Nano A1 goes to BTN3
  • Nano A0 goes to BTN4
Finally the pinout for the C2N connector to the board:
CN2 to Tapuino connector pinout

You will need to break out 8 pins from a pin header.
Solder the C2N connector to the pins in the following manner:

  • GND to PIN 1
  • PWR to PIN 2
  • READ to PIN 3
  • MOTOR to PIN 4
  • SENSE to PIN 5
  • WRITE to PIN 8
I recommend you heat-shrink the pins as above.

Your connector should look like the one above, the colour to pin map in my case is:
  • Black (GND) to PIN 1
  • Green (PWR) to PIN 2
  • White (READ) to PIN 3
  • Red (MOTOR) to PIN 4
  • Blue (SENSE) to PIN 5
  • Brown (WRITE) to PIN8
Should look something like this:
C2N connected to the Tapuino
NOTE:

PIN 1 (GND) is connected to the left-most pin of the female pin header.

Now all that is left to do is flash the sketch to the Nano, disconnect it from USB, insert an SD Card with TAP files, connect the Tapuino to the C64 and enjoy!

The U.I. is controlled as follows:

BTN 1 is SELECT
BTN 2 is ABORT (during a load) or BACK one directory if browsing
BTN 3 is PREVIOUS
BTN 4 is NEXT

If you have directories on your SD card they will be indicated by an arrow in the right-most column of the LCD where the filename is displayed. Long filenames are now supported!


Caution: Do not connect the Nano to both the C64 and PC. Also check all soldering very carefully for shorts before wiring up to your beloved machine!

The astute reader will note that the bus connector has 2 additional pins that are not connected: CTRL1 and CTRL2. These are used in the MUX board to allow switching between the C64 and a real Datasette as a target device and will be covered in a future blog.

Hope you enjoyed this, it was a helluva post to write!

-(e)

Saturday, January 10, 2015

Arduino Pro Micro Arcade Controller

A bloke at my local Makerspace decided to build himself a table top arcade machine, which came out pretty damn well!


I had had a similar plan a while back, but never got around to it and so had the buttons and controls on hand which I sold to him. With the build complete and the controls installed, he needed a way to hook the controls up to the MAME PC in the cabinet. I'd been playing around with some Arduino Pro Micro boards for a similar purpose (hooking up retro C64 joysticks to my PC) so these seemed like a really good option. At the current price on eBay of $6.60 from my favourite supplier, this was a really cheap option.

As there were 2 joysticks with 8 buttons each, a single Pro Micro wasn't going to be sufficient, so we used 2. The basic vero board layout was:

2 Joystick Vero board layout

Pretty simple, with just some track cutting to separate the two Pro Micro. Once the tracks were cut we soldered in so 24 pin wide DIP sockets, the end result looked like this:


The wiring to the controls for each Pro Micro was:

PINLEFTRIGHT
2UpUp
3DownDown
4LeftLeft
5RightRight
6Button 1Button 1
7Button 2Button 2
8Button 3Button 3
9Button 4Button 4
10Button 5Button 5
16Button 6Button 6
14Button 7 (Player 1)Button 7 (Player 2)
15Button 8 (Left Paddle or Insert Coin)Button 8 (Right Paddle or Insert Coin)

Once wired up all we needed was some firmware. The Arduino IDE comes with some basic USB HID support for keyboards and mice, but doesn't feature any joystick HID descriptor. To fix this you'll need to change two files in the core Arduino software: HID.cpp and USBAPI.h. These can be found in the hardware\arduino\cores\arduino for the 1.0.6 build and somewhere similar for the newer IDE builds.

NOTE: These files are based on code from this blog: www.imaginaryindustries.com/blog/?p=80

Add the following class definition to USBAPI.h

//================================================================================
//================================================================================
// Joystick
//  Implemented in HID.cpp
//  The list of parameters here needs to match the implementation in HID.cpp


typedef struct JoyState
{
  uint8_t  xAxis;
  uint8_t  yAxis;
  uint8_t  buttons;  // 8 general buttons
} JoyState_t;

class Joystick_
{
public:
  Joystick_();

  void setState(JoyState_t *joySt);

};
extern Joystick_ Joystick;

Then in HID.CPP you'll need to add the Joystick descriptor, look for:

#ifdef HID_ENABLED

and add:

#define JOYHID_ENABLED

Then find:

const u8 _hidReportDescriptor[] = {

and add in:

#ifdef JOYHID_ENABLED

// 8 buttons, X and Y

 0x05, 0x01,   // USAGE_PAGE (Generic Desktop)
 0x09, 0x04,   // USAGE (Joystick)
 0xa1, 0x01,   // COLLECTION (Application)
  0x85, 0x03,   // REPORT_ID (3)  (This is important when HID_SendReport() is called)

  //Buttons:
  0x05, 0x09,   // USAGE_PAGE (Button)
  0x19, 0x01,   // USAGE_MINIMUM (Button 1)
  0x29, 0x08,   // USAGE_MAXIMUM (Button 8)
  0x15, 0x00,   // LOGICAL_MINIMUM (0)
  0x25, 0x01,   // LOGICAL_MAXIMUM (1)
  0x75, 0x01,   // REPORT_SIZE (1)
  0x95, 0x08,   // REPORT_COUNT (8)
  0x81, 0x02,   // INPUT (Data,Var,Abs)

    0x05, 0x01, // USAGE_PAGE (Generic Desktop)
    0xa1, 0x00, // COLLECTION (Physical)
      // 2 8bit Axis
      0x09, 0x30, // USAGE (X)
      0x09, 0x31, // USAGE (Y)
      0x15, 0x80, // LOGICAL_MINIMUM (-128)
      0x25, 0x7F, // LOGICAL_MAXIMUM (127)
      0x75, 0x08, // REPORT_SIZE (8)
      0x95, 0x02, // REPORT_COUNT (2)
      0x81, 0x02, // INPUT (Data,Var,Abs)
    0xc0, // END_COLLECTION
 0xc0     // END_COLLECTION

#endif

Finally you need to add the implementation for the joystick:

//================================================================================
//================================================================================
// Joystick
//  The report data format must match the one defined in the descriptor exactly
//  or it either won't work, or the pc will make a mess of unpacking the data
//

Joystick_::Joystick_()
{
}


#define joyBytes 3   // should be equivalent to sizeof(JoyState_t)

void Joystick_::setState(JoyState_t *joySt)
{
  uint8_t data[joyBytes];

  data[0] = joySt->buttons;  // Break 32 bit button-state out into 4 bytes, to send over USB
  data[1] = joySt->xAxis;  // X axis
  data[2] = joySt->yAxis;  // Y axis

  //HID_SendReport(Report number, array of values in same order as HID descriptor, length)
  HID_SendReport(3, data, joyBytes);
  // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from
}

Now that all the ground work is done, a simple .ino file will handle the joystick interface:

JoyState_t joySt;

#define MAX_AXIS 4
#define Y_MIN  0
#define Y_MAX 1

#define X_MIN  2
#define X_MAX 3

uint8_t joy_axis[MAX_AXIS] = {2,3,4,5};

#define MAX_BUTTONS 8
uint8_t joy_buttons[MAX_BUTTONS] = {6,7,8,9,10,16,14,15};

void setup()
{
  uint8_t i;
  pinMode(13, OUTPUT);

  for (i = 0; i < MAX_AXIS; i++) {
    pinMode(joy_axis[i], INPUT);
    digitalWrite(joy_axis[i], HIGH);
  }

  for (i = 0; i < MAX_BUTTONS; i++) {
    pinMode(joy_buttons[i], INPUT);
    digitalWrite(joy_buttons[i], HIGH);
  }

  joySt.xAxis = 0;
  joySt.yAxis = 0;
  joySt.buttons = 0;

}

void update_stick() {
  uint8_t i;

  joySt.xAxis = 0;
  joySt.yAxis = 0;
  
  if (digitalRead(joy_axis[Y_MIN]) == LOW) {
    joySt.yAxis = 128;
  } else if (digitalRead(joy_axis[Y_MAX]) == LOW) {
    joySt.yAxis = 127;
  }

  if (digitalRead(joy_axis[X_MIN]) == LOW) {
    joySt.xAxis = 128;
  } else if (digitalRead(joy_axis[X_MAX]) == LOW) {
    joySt.xAxis = 127;
  }

  joySt.buttons = 0;

  for (i = 0; i < MAX_BUTTONS; i++) {
    if (digitalRead(joy_buttons[i]) == LOW) {
      joySt.buttons |= 1 << i;
    }
  }

  Joystick.setState(&joySt);
}

void loop() {
  update_stick();
}

Thes files can be obtained from here: Joystick HID Files but I suggest that you patch the HID.cpp and USBAPI.h files manually to account for any variance between your and my Arduino IDE.

Have fun and keep on hacking!
-(e)

Friday, August 1, 2014

Understanding Rotary Encoders

While attempting to improve the physical interface to the Tapuino I thought about Rotary Encoders which I've wanted to experiment with for a while. I managed to obtain some locally for a fairly reasonable price and set about looking for a solid code base to use. There seem to be a huge number of libraries and as many complaints about the quality of these libraries. Eventually I stumbled across this blog post which promised: Rotary encoders, done properly

The premise looked really promising: a simple state machine for matching encoder state transitions and some lightweight code. Unfortunately the library behaved rather oddly. The first step was always missed and transitioning from one direction to another would also miss a step. Looking at the code it seemed that the state transition table was incorrect in some way, but for the life of me I couldn't reverse engineer the logic as the transitions seemed counter intuitive.

I decided to recreate the table from first principles so that I would completely understand the logic behind the idea and ended up with a solution that seems to work without error which I will explain below.

Firstly some basic theory. Rotary encoders generally have two output pins and a common pin.



Mechanical Rotary Encoder, center pin is common.


As the shaft is rotated the pins are switched on and off in a specific sequence. For example, rotating the shaft clockwise produces the following output:

Output Stage  Pin A  Pin B 
000
110
211
301
400

The first and last entries are when the encoder is at rest. Each set of outputs is one 'click' in an encoder with 'dedents'. When rotated in the counter clockwise direction the code is reversed:

Output Stage  Pin A  Pin B 
000
101
211
310
400


You can get more detail on this Wikipedia article under the section "Incremental rotary encoder". The theory from the post mentioned above was to build a state machine to map these states. In the post the author describes a state machine with seven possible states and gives each a value. Each state name maps to an output state in the tables above. The states and values in the original code are:

R_START0x0
R_CW_FINAL0x1
R_CW_BEGIN0x2
R_CW_NEXT0x3
R_CCW_BEGIN0x4
R_CCW_FINAL0x5
R_CCW_NEXT0x6

Where: R_START is the common 0-0 value and used as a beginning and ending state, R_CW_BEGIN would map to the 1-0 output state, R_CW_NEXT to the 1-1 output state, R_CW_FINAL to the 0-1 output stage and so on. While the value of the states is arbitrary, I chose to change the values so that they followed a 'logical' order:

R_START0x0
R_CW_BEGIN0x1
R_CW_NEXT0x2
R_CW_FINAL0x3
R_CCW_BEGIN0x4
R_CCW_NEXT0x5
R_CCW_FINAL0x6
 
 
The code then goes on to read the state of pins A and B and computes a combined pin state as:

value = A << 1 | B


In other words the combined pin state can have the binary values 00, 01, 10, 11 or decimal 0, 1, 2, 3. This pin state is then used to perform a transition in a state table. The original state table looks like this:

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
The current state is the row in the table and the combined pin state is used to find a column in the table indicating the next state to transition to. The code that does this looks like this:

state = ttable[state & 0xf][pinstate];

The DIR_CW and DIR_CCW values are OR'd into the state to signal that a transition has occurred. So at starting state R_START with pin values 1-0 (the first set of values in a clockwise transition) the table above would transition to R_CCW_BEGIN....

And I'm not sure how that is supposed to be correct. Lets find out what the correct values should be by mapping this out. Here is a basic table describing the state machine. States as rows and transitions as columns:

Basic Layout

The next step is to realise that if we are in a state and we read the same pin values that got us into this state, we should stay in the state:

Transitioning back to the same state
So, if we are in R_START and read 0-0 we should transition back to R-START, similarly if we are in R_CW_BEGIN and read 1-0 we should transition back to R_CW_BEGIN. With this out of the way, we can map out the transitions for clockwise:


Clockwise direction state map added
Here in sequence:
  • State = R_START, pins read 1-0, transition to R_CW_BEGIN (row 1, column 3)
  • State = R_CW_BEGIN, pins read 1-1, transition to R_CW_NEXT (row 2, column 4)
  • State = R_CW_NEXT, pins read 0-1, transition to R_CW_FINAL (row 3, column 2)
  • State = R_CW_FINAL, pins read 0-0, transition to R_START (row 4, column 1)
At the point of the final transition, the pattern has been matched and we should emit a Clockwise Event.

Similarly we can map out the transitions for counter clockwise:

Direction 2 state map added
Here in sequence:
  • State = R_START, pins read 0-1, transition to R_CCW_BEGIN (row 1, column 1)
  • State = R_CCW_BEGIN, pins read 1-1, transition to R_CCW_NEXT (row 5, column 4)
  • State = R_CCW_NEXT, pins read 1-0, transition to R_CW_FINAL (row 6, column 3)
  • State = R_CCW_FINAL, pins read 0-0, transition to R_START (row 7, column 1)
At the point of the final transition, the pattern has been matched and we should emit a Counter Clockwise Event.

So now that we've mapped out the two complete transitions there is only one thing left to do. All of the blank entries in the table map out illegal states. If we find an illegal state all we need to do is transition back to R_START so that the next legal set of pin inputs can be followed:


Error state map added
In code this would look like this:

unsigned char ttable[7][4] = {

  {R_START, R_CCW_BEGIN, R_CW_BEGIN,  R_START},

  {R_START, R_START,     R_CW_BEGIN,  R_CW_NEXT},

  {R_START, R_CW_FINAL,  R_START,     R_CW_NEXT},

  {R_START, R_CW_FINAL,  R_START,     R_START},

  {R_START, R_CCW_BEGIN, R_START,     R_CCW_NEXT},

  {R_START, R_START,     R_CCW_FINAL, R_CCW_NEXT},

  {R_START, R_START,     R_CCW_FINAL, R_START},

};

Adding in the flags to indicate the final state transitions then becomes extremely logical:

ttable[R_CW_FINAL][R_START] |= DIR_CW;
ttable[R_CCW_FINAL][R_START] |= DIR_CCW;

"When in the final state and transitioning to the start state, emit the direction"

Well this was really interesting to figure out and I hope it helps some folk out there. Now I need to implement this code into the Tapuino...

Till next time, hack on!
-(e)



Monday, July 28, 2014

Tapuino Part 3: Write support and some circuit changes

Well the Tapuino is out in the wild and has been successfully built by another user!

(please note, most recent build instructions are now here: http://sweetlilmre.blogspot.com/2015/03/building-tapuino-r2.html)

Whilst that has been going down I've been hacking away on the code base extending the firmware to handle:

  • Long filename support: I've moved over to the FatFs library to enable this
  • Write support! This was a killer but finally works... if you have a FAST SD Card.
  • Many bug fixes (I2C display now works across more backpacks)
  • Restructuring and code cleanup
There has been a minor HW change to facilitate write support:

The C64 Datasette write line now must be connected to pin D8 of the Nano. If you built the Tapuino as per my previous post all that should be involved is moving it across to the correct pin, possibly soldering up a new header. The breadboard diagram and Fritzing file in GitHub have been updated accordingly:

New wiring
Also, I put in the 5V and GND lines that were missing before.

Write support has been tested with some simple BASIC save files and also via the Elite save game mechanism and all appears well. Files are written to TAP format in a folder on the root of the SD Card called "Recorded" (this folder will be auto-created for you) and have the filename "rec-XXXX.tap" where XXXX is a 4 digit decimal number.

At this point the Tapuino is functionally complete. I'd like to get a few more folk to build and use this to help track down the inevitable bugs and also work on a few more features. Features I have been thinking about include:

  • Button repeat functionality for scrolling through long lists of files.
  • A name input mechanism for naming recorded files.
Go forth and build!
-(e)

Wednesday, July 16, 2014

Tapuino Part 2: Building the $20 C64 Tape Emulator

Hi,

(please note, most recent build instructions are now here: http://sweetlilmre.blogspot.com/2015/03/building-tapuino-r2.html)

Having detailed the Tapuino in my last post, its now time to get down to the specifics of how to build one. In keeping with the low-cost requirement I developed the initial prototype on a breadboard and then moved that design onto strip or vero board. The vero board based construction will eventually live in a nice neat project box (when I finally get there).

DISCLAIMER: If you build this and it blows up your C64, sets your house on fire, kidnaps your dog or any other negative occurrence, I take no responsibility or liability whatsoever. That said I will do my best to help troubleshoot any builds.

So lets get started. Firstly a bill of materials:

Major components:
  • Arduino Nano V3
  • 16x2 LCD Display with I2C backpack
  • SD Card module with built-in level conversion
  • 40 wire Dupont female-female 'ribbon'
I got all of this from TxHang Electronics on eBay. They are cheap and ship relatively quickly, so are worth it in my book. Here is an example shopping list:


Addition components:
  • Piece of vero board. The one I got was 100mm wide x 200mm long. This is also known as strip board and must be the kind with strips of copper (as opposed to individual 'cells')
  • 32 pin (16x2) WIDE dip socket (this is what the Nano will plug into)
  • 6 pin (3x2) dip socket (for the opto-coupler)
  • A strip of male pin headers
  • A strip of male right-angle pin headers
  • A strip of female pin headers (sockets)
  • 5x 10K Ohm resistors
  • 1x 430 Ohm resistor
  • 4x Tactile switches (6x6)
  • 1x 4N25 Opto-coupler
  • Some jumper wire (I use single core wire from a piece of telephone cable)
Here are examples of the headers:


So lets build the main board first. You'll want to put it together like this:

Top view of the main board

Note the minimum dimensions of the board: 26x15. You may wish to make the board larger to allow for mounting holes.

R1 = 10K Ohm
R2 = 430 Ohm
Green blocks = straight header pins.

Break the header pins into appropriate size groups:
3x3 pins
1x1 pin
1x6 pins
and cut the female pin headers to size (mine were 40 pin, so cut down to 19 pins)

Bottom view of the main board
The lighter yellow bits are where the vero board has been cut. It is essential that you check that these tracks are cut properly. Use a multimeter to test for continuity between the tracks once cut. To cut the tracks on my prototype I used a small sharp drill bit that was luckily a perfect fit.
Please take note of the cut track between the two pins of R2.

I would suggest that you solder in this order:
  1. 32 pin wide dip
  2. 6 pin dip
  3. 2x3 pin header group next to the 6 pin dip
  4. Remaining pin headers
  5. Jumper wires

Feel free to extend the pin headers to access additional pins on the Nano if you like, I just wanted to keep it simple for wire-up later and expose only the pins necessary.

Next up is the button board:

Top view of the button board

Note the minimum dimensions of the board: 22 x 21. You may wish to make the board larger to allow for mounting holes.

R1, R2, R3, R4 are all 10K Ohm
Green pin headers are right angle.
The pinouts of the green pin headers, left to right are as follows: GND, PWR, BTN1, BTN2, BTN3, BTN4

Bottom view of the button board

Take careful note of the tracks to cut:
  • There is a cut between each end of each resistor
  • Between the poles of the switches
  • On the 6th track (from the left) to isolate button 3 from button 1
Also note that the jumper wires for the power and ground lines are soldered through to multiple points. I achieved this by cutting the wires into individual sections:
  • power line (top most line) there are 4 jumper wires of 3, 6, 6, 6 tracks in length.
  • ground line (under the switches) there are 4 jumper wires of 4, 6, 6, 6 tracks in length.

Now lets install the components and connect it all up.
Firstly install the 4N25 opto-coupler into the 6 pin socket:

Installing the 4N25 opto-coupler

Note the small dot on the chip, this indicates pin 1. The chip should be oriented such that pin 1 connects through to the 440 Ohm resistor (R2).

Next the Nano:

Installing the Nano

As the Nano has 2x15 pins and the socket 2x16 pins, care must be taken to place the Nano correctly. The Nano must be aligned so that the empty socket pins are on the right most pins of the socket as per the image above i.e. the Nano is mounted as close as possible to the opto-coupler.

If you trace out the circuit you will observe that the 2x3 pin headers between the opto and the Nano expose a ground and power rail (left is GND, right is PWR). You will use these rails to provide power to the LCD, SD Card and Button breakout boards.

Connect in the following manner:

LCD:
  • Power and Ground go to the rails described above
  • Nano A5 goes to SCL
  • Nano A4 goes to SDA
SD Card:
  • Power and Ground go to the rails described above
  • Nano D13 goes to SCK
  • Nano D12 goes to MISO
  • Nano D11 goes to MOSI
  • Nano D10 goes to SS
Button Board:
  • Power and Ground go to the rails described above
  • Nano A3 goes to BTN1
  • Nano A2 goes to BTN2
  • Nano A1 goes to BTN3
  • Nano A0 goes to BTN4
Finally the pinout for the C2N connector to the board:


You will need to break out 15 pins from a pin header i.e. have 15 continous pins.
Solder the C2N connector to the pins in the follow manner:

  • MOTOR to PIN 1
  • GND to PIN 4
  • PWR to PIN 5
  • WRITE to PIN 12
  • READ to PIN 13
  • SENSE to PIN 15

Remove all other non-connected pins: e,g, pins 2, 3 6-11 and 14. I recommend you heat-shrink the pins as above.

Your connector should look like the one above, the colour to pin map in my case is:
  • Red (MOTOR) to PIN 1
  • Black (GND) to PIN 4
  • Green (PWR) to PIN 5
  • Brown (WRITE) to PIN 12
  • White (READ) to PIN 13
  • Blue (SENSE) to PIN 15
Final assembly should look something like this:
Final Assembly! YES! :)

NOTE:

PIN 1 (RED/MOTOR) is connected to the left-most pin of the female pin header.

Now all that is left to do is flash the sketch to the Nano, disconnect it from USB, insert an SD Card with TAP files, connect the Tapuino to the C64 and enjoy!

The UI is controlled as follows:

BTN 1 is SELECT
BTN 2 is ABORT (during a load) or BACK one directory if browsing
BTN 3 is PREVIOUS
BTN 4 is NEXT

If you have directories on your SD card they will be indicated by an arrow in the right-most column of the LCD where the filename is displayed. Currently only 8.3 format names are supported. I will look into LFN names at a later date.


Caution: Do not connect the Nano to both the C64 and PC. Also check all soldering very carefully for shorts before wiring up to your beloved machine!

Hope you enjoyed this, it was a helluva post to write!

-(e)