Reddit/r/RetroBattlestations BASIC Week 3– C64 port

Under The Sea: BASIC Week 3 C64It’s BASIC Week on Reddit/r/RetroBattlestations and I ported the BASIC Week program “Under the Sea” to the Commodore 64. The original code was written by FozzTexx for the IBM PC which allows for variable names longer than two characters. The Commodore 64 BASIC version 2 would probably still work using the longer names, it would just ignore everything after the first two characters. Doing this though would run the risk of overwriting variables so it was best to convert them. You can find a list of the variable name conversions at the end of the post.

If you’re keen to type the program in yourself, you can do so here. There’s a few special characters used the code. “CBM-” means hold the Commodore key (lower left) and hit the character after.

If you want to simply run the program from a disc image or to make a floppy, you can download a D64 disk image of Under The Sea here.

The BASIC version is quite slow and there’s room for optimization of the display code. Instead, I ran the code through the BLITZ! BASIC compiler and it runs much faster. This version is on the disc as “c/underthesea”

There’s three keys used the game. ‘A’ makes the turtle (you) go up, ‘Z’ goes down and ‘Q’ will quit the game.

Variable name conversion

Turtle$ = t$
TurtleWidth = tw
TurtleHeight = th
TurtleErase$ = te$
TrutleDead$ = td$
Enemy$() = nm$()
EnemyErase$ = ee$
EnemyW = ew
GameOver$ = go$
GOWidth = gw
GOHeight = gh
AirMax = am
Sea$ = se$
TurtleY = ty
Surface = sf
Score = sc
LastY = ly
TurtleX = tx
NumEnemies = ne
BubbleX = bx
BubbleY = by
Enemy X = ex
Enemy Y = ey
EnemyHit = eh
Food$ = f$
FoodX = fx
FoodY = fy
NewX = nx
NewY = ny
EnemyC = ec
NumBubbles = nb
NumFood = nf
exV = xv
eyV = yv
rows = rw
cols = cl

3D Visualization on the Commodore 1520

Riz1520_Plots00011
NOTE! Split gears causing plot errors? New replacement Alps gears for the Commodore 1520, Atari 1020, etc are now available! Click here to order your set.

Recently on the Lemon64 forum, user Rizthomas posted some excellent scans of some plots that he did on a Commodore 1520 Printer/Plotter back in 1986. The plots were well executed and very intricate. Some were 2D “string art” and some were 3D functional models. Unfortunately, Rizthomas was unable to locate the original disks for his plots (still hopeful they’ll turn up!) but was generous enough to point everyone in the direction of where he began.

One route was Transactor Magazine Volume 6, Issue 4 which contained a program called The Projector by Ian Adam of Vancouver, B.C. The program was of combination BASIC that built on top of a series of machine language routines (from Transactor Volume 5, Issue 6) that made it easy to draw lines, circles, and text on a hires screen. The routines were called with a SYS command from BASIC and were passed coordinates as variables. This made it incredibly easy to patch the program to also send those coordinates to the Commodore 1520 Printer/Plotter with a few modifications.

  • The hires screen coordinates (320×200) doesn’t match the 1520 plotter (480,999) but that’s easily taken care of by scaling the coordinates by a factor of 1.5.
  • The program includes several functions to plot contained in REM statements. I broke those out into a menu system so you can choose a function to plot.
  • I eventually matched Rizthomas’ color choices by making horizontal lines blue, vertical lines green, bounding box green and text black (on the plot only).
  • The origin of the plotter (current pen location at start) is (0,0). Below that point is the negative Y axis so you need to advance the paper up by 300 and then send the “I” command which sets a new “relative origin” point. Now the coordinate systems match screen coordinates (bottom left is (0,0)). Sending the command “R” instead of “M” for moving (pen up) will now use the new relative origin as does “J” instead of “D” for drawing (pen down). The 1520 manual is a great resource to understand the coordinate system of the plotter.

3d 1520 plots

You can download the program (and required ML program) here.

The nice thing about the program is that it will draw a line on the screen while drawing it on the printer simultaneously so you can see both evolve together. Enjoy and a big thanks to Rizthomas for the pointers to the code! If you’re able to get it working, let me know in the comments (and let’s see what you plotted).

Here’s a quick Vine of the plotter working:

DIY RS-232 Interface for Commodore C64 for under $15

If you have a Commodore 64, chances are you’ll eventually need to connect a modem or other serial device to it. You’ll find that’s not quite that easy since the C64 doesn’t have a standard RS-232 serial port. What it does have is called the “user port” and it can do serial over this port but it needs to be changed from TTL levels (0 to +5v) to RS-232 levels (-15v to +15v).

If you’ve ever attempted to purchase a VIC-1011a terminal type, SwiftLink or Turbo232 from eBay you’ll quickly find out that the price gets out of hand. Expect to pay upwards of $100 or more for these adapters.

Luckily, there’s an inexpensive way to get a RS-232 port on your C64 and it’ll cost you less than $15. Ready?

You’ll need these parts for the project.

Connect the RS232-TTL module directly to the C64 user port edge connector using the table below.

RS232-TTL Module C64 User Port
GND A & N
TXD M
RXD B & C
VCC 2

Update! Alwyz from 1200baud suggested that connecting VCC isn’t necessary and potentially dangerous. I’ve had zero problems with mine as listed here. I’m providing this warning so you can make your own decision!

C64 RS-232 Adapter

Observe which side of the user port connector is the top (it’s the one with numbers– letters are on the bottom). It’s helpful to write on it with marker. For wire I used female jumper wire that I cut one end off. For GND and RXD you’ll need to jumper two of the pins together on the user port connector. I used a small bit of CAT5 solid core wire.

Once you’ve got it connected, add the null modem adapter and connect your modem. You may need to also use a gender changer and/or a 9 pin to 25 pin adapter depending on your modem.

Fire up CCGMS, Novaterm or Striketerm, set the baud rate to 2400, set the port to the user port and give it a few “AT” commands. You should see “OK” being returned. If it doesn’t, make sure you have a null modem adapter (test it on another machine to confirm) and double check your connections.

As with any tutorial you find online, be responsible and double check my work and your work before proceeding.

How to get software to disk for your Commodore 64

Commodore 64It’s a question that pops up from time to time on forums from Lemon64 to Reddit C64.

“Yes! I just got a Commodore 64!! Now how do I get disk images onto disk so I can do something?”

It’s not straight forward. Folks in the Apple II world have a fantastic program called ADTPro that can work over a simple audio cable connected to your laptop headphone and microphone jack (or serial). Doesn’t get any easier than that.

On the Commodore, disc images are stored in .D64 format which is an image of a standard 1541 floppy. Most software you find is available this way. You may also find .D71 and .D81 which are for 1571 and 1581 formats but these are less common. A great place to find C64 software is the CBM8BIT.com Search. Once you have your disk images, you’re ready to make some floppies. Below are some of the options to “burn” disk images for your Commodore 64.


uIEC/SD2IECuIEC/SD2IEC ($50-60) is probably the easiest overall solution. With this small device, you can load .D64 images from your Mac or PC onto a SD card. Inserting into the uIEC, it will show up to the C64 as an extremely large volume. But merely having a .D64 image doesn’t get you very far– you need to “burn” the image to a real floppy. Fortunately, there’s D64it which can do just that. It’s a little slow as the author admits, but it gets the job done. Things are sped up considerably if you have the JiffyDOS ROM ($20) installed in your C64 since the uIEC is JD compatible. Don’t forget a 6-pin IEC cable!


64NIC+64NIC+ ($50-59) adds Ethernet capability to your Commodore 64 as well as a ROM socket that can accommodate up to 256kB ROMs. With networking capability, now you’re able to use WarpCopy64 which can upload and download entire disc images to your PC. There’s a bit of a chicken and egg problem here since you’re going to need WarpCopy64 on disk first before you can create new disks.


ZoomFloppyZoomFloppy ($35) is a great solution to connect your Commodore 1541 to your Mac or PC via USB. ZoomFloppy is a modern version of the “X” series cables which required an old PC with a parallel port plus knowledge of IRQ and ports (see below). After installing OpenCBM software on your Mac or PC, you can read and write D64 images quickly and easily– no fuss. Hands down, this is my preferred way to read and write floppies.


If you’re lucky to have a terminal program already on floppy on your C64, you can do the serial route. Of course, you’ll also need an adapter that plugs into the C64 user port to give you standard RS-232 signals. These can be difficult to come by if you don’t have one, like the Commodore made VIC-1011a. One could also build this USB to RS-232 interface for your C64 for $15.


If you have a PC that’s old enough to have a parallel port on the motherboard, you might have good luck with “X” series parallel cables. These cables connect your parallel port to the IEC port of a 1541. From there, you can run Star Commander in DOS mode to read and write files and images. I started using this method years ago but abandoned it for the ZoomFloppy.

So there you have it. There’s no shortage of solutions and every solution is most likely going to cost you something. But each is a great investment and keeps the scene going with folks creating new methods. This list isn’t exhaustive– if you know of one or have experience with any of these, leave a comment!

Reddit r/retrobattlestations Commodore 64 Port


For the next two weeks, it’s BASIC Week 2 at Reddit r/retrobattlestations. You can participate with your Commodore 64 or at least play along with your favorite emulator. I’ve ported the code to the C64 and you can get the code from the thread on Reddit. Or you can download the D64 image here to make your own disk or to use with an emulator like VICE.

Have fun!

DIY C64 Diagnostic and Dead Test Carts

If you’ve ever attempted to repair a dead Commodore 64 beadbin, you know how frustrating it can be. You’re lucky if the machine turns on and shows something on the screen. This at least gives you some clues as to the problem. However, more often and not, you’re stuck with a blank screen. It doesn’t tell you much other than just about any chip in the computer is bad, or even a bad power supply. After checking the obvious things like missing chips, reseating socketed chips and checking the power supply voltages, the next place to go would be one of the two diagnostic carts that were available from Commodore service technicians.

The two test carts that were available are the C64 Diagnostic cart and the C64 Dead Test cart. Together, these carts are very useful in identifying problems. In order to use them, you need them in a cartridge. The diagnostic cart also had a cable harness that would test certain ports– it’s not required but will report false problems if not present. If you’ve followed my posts, you’ll know that I have a tutorial on how to convert an existing cartridge into a EPROM carrier board. In this case, instead of creating a 24 to 28 pin adapter, I’ve purchased the Retro Innovations 2364 Adapter for $5. It’s well worth the price.


In both cases, I’ve used a Commodore cartridge with ASSY # 326173-01. The thing you’ll find odd about the picture is the carts look completely different but have the same ASSY number. The good news is they behave the same way.

There are solder jumpers on the cart labeled J1 through J5. These control certain lines on the cartridge port that tell the C64 what type of peripheral is connected. Below is a table of the settings for the two carts.

C64 Diagnostic Cart Jumpers
J1: Closed (ROMH)
J2: Open (ROML)
J3: Open (GAME)
J4: Closed (EXROM)
J5: Open (I/O 2)

C64 Dead Test Cart Jumpers (Ultimax Mode)
J1: Open (ROMH)
J2: Closed (ROML)
J3: Closed (GAME)
J4: Open (EXROM)
J5: Closed (I/O 2)

DIY Cynthcart for Commodore 64

I’ve wanted to create my own cartridges for the C64 for a while now. I have a few old Commodore cartridge games like Clowns and Kickman that would better serve me as, say, a diagnostic cartridge or Cynthcart. These boards are ASSY 326173-01 and seem to be common so you should be able to pick one up cheap.




The first hurdle was burning EPROMs. I took a chance on eBay and bought a TOP 853 universal programmer. It was shipped from China and arrived in about 3-4 weeks. I was struggling to get it working over USB on my Mac to Virtual Box to a Windows XP VM but I figured it out (hint: disable USB 2.0 (EHCI) Controller for the VM).

I erased the chips using a Pocket Purifier battery operated hand held UV light that I picked up from Amazon. It took anywhere between 30 minutes to 2 hours (most 1 hour) to completely erase the EPROMs. I’m using 27c256 (32 kilobyte) chips which are 28 pins. Cynthcart is an 8 kilobyte ROM so I copied the ROM four times on the chip– only one of the copies will be used. You could add four different 8k ROMs and select one with dip switches on the higher address lines (A13 and A14 I believe).

The C64 cartridges I’m going to use have 24 pin chips on them. This presents a problem. Luckily the pinout is almost the same that it’s rather easy to reroute the pins. I followed the C64 ROM guide on Symlink.dk which had the pinout from the board to the new socket.

24 to 28 pin EPROM

You’ll need to desolder the old chip at U1. I used a 28 pin socket, bent out pins 1, 2, 20, 23, 26, 27, 28 on the socket. I soldered in small wires (from an 80 pin IDE cable) into the board on pins 18, 21, 24. See the schematic above to know which pins connect to which wires. Pay attention to the pin numbering– it will get confusing with the socket on top with different pin numbers. Also, make sure you orient the socket and the chip in the right direction. Pin numbers start upper left of the chip notch, down to bottom left, then to bottom right, then up to upper right.

There are 5 “jumpers” (solder bridge pads) on the board. This forum post on Lemon 64 was a great help but turned out not to work for me 100%. I opened J2, J5 and closed J1, J3, J4. The EPROM is too tall for the case to close completely but the screw will hold it together enough.

There you have it. This should work for any 8 kilobyte game that maps to $8000. Best part is since you’ve used a socket, the software can be easily swapped with something else. Enjoy!

C64 USB Keyboard works with iPad


Just a follow up to the C64 USB keyboard Arduino project that I made last week. I was curious if it would work on the iPad using the iPad Camera Connection kit. So I tried it out and was greeted with the error “Cannot Use Device” and “The connected USB device is not supported.” I dismissed the window and tried anyway and it worked! I was able to type in any application.

Any application that is except the Manomio C64 emulator on the iPad/iPhone. I doubt that any USB keyboard would work there, not just mine. Maybe support for USB keyboards could be added?

Commodore 64 Keyboard Gets The USB Treatment Thanks to Arduino

Recently I’ve been repairing a batch of broken Commodore 64’s that I scored on eBay for cheap. Out of the repairs, two boards were beyond hope but still had some usable parts on them so motherboards became donor boards. That left me with a couple empty cases and keyboards so I decided to make a Commodore 64 USB keyboard.

There’s already a nice product called Keyrah that does just this (plus a lot more) and I recommend you checking it out as it adds Amiga keyboard and joystick support.

But if you’re like me and want the challenge, I decided to go the maker route.

First, I searched for any such projects– no sense in re-inventing the wheel. I found a project by Mikkel Holm Olsen called C64 USB Keyboard. It used an Atmel ATMega-8 chip which I’ve learned is very similar to Arduino’s 168/328P chip. It might work but with some modifications– beyond my skill set today. I shelved this project and continued.

The keyboard is basically an 8×8 matrix keypad. There’s already a keypad library for Arduino. A couple of things that I discovered while using this library. One, don’t use pin 13 with the C64 keyboard. It’s probably because of the built in resister and LED that causes the pull ups to not work. An outside pull up might fix this. Two, the library only supports single keypresses. This is a bummer since you often will press two keys (i.e. the shift key, control, etc). But I worked around it. I put together a quick harness that will connect the Commodore 64 keyboard to the Arduino, aligning the rows and columns to the right pins. I like to make my projects the least destructive way so I use a lot of tape, jumpers and breadboards.

Getting the Arduino to talk USB makes use of the V-USB library which has been ported to Arduino. I really like this implementation because it’s all handled by the Arduino and needs very little passive glue on the outside to make it work. Below is a diagram of how to hook up USB to the Arduino. The values on the diodes are pretty strict and must be 3.6V 500mW zener diodes (although I hear 250mW is better). More information can be found in the V-USB documentation.

I made a small change to the V-USB code and moved the USB data (-) from Arduino pin 4 to pin 3– just edit usbconfig.h inside the UsbKeyboard library. I also commented out the optional connect/disconnect on pin 5 because I simply don’t have the pins to spare! Connected, the inside looks like this.

Commodore 64 USB Keyboard Inside

Commodore 64 USB Keyboard Arduino

Arduino V-USB Glue

The pin mapping goes like this:
C64 Pin Arduino Pin
Column 0 = 13 -> 4
Column 1 = 19 -> 5
Column 2 = 18 -> 6
Column 3 = 17 -> 7
Column 4 = 16 -> 8
Column 5 = 15 -> 9
Column 6 = 14 -> 10
Column 7 = 20 -> 11
Row 0 = 12 -> 12
Row 1 = 11 -> 0 (This was pin 13 if you’re wondering why the break in continuity)
Row 2 = 10 -> 14 (Analog 0)
Row 3 = 5 -> 15 (Analog 1)
Row 4 = 8 -> 16 (Analog 2)
Row 5 = 7 -> 17 (Analog 3)
Row 6 = 6 -> 18 (Analog 4)
Row 7 = 9 -> 19 (Analog 5)

I power the Arduino via the incoming USB. To get it to be recognized properly by your computer, unplug the USB programming cable from the Arduino and then plug in the USB cable to the V-USB side. Otherwise it will not be recognized. It makes for a lot of cable swapping unfortunately while coding. I also powered the C64 power LED for nostalgia (this may be a good use for pin 13).

Speaking of code, I needed to define some key codes that were missing from the UsbKeyboard library. This was fairly straight-forward by looking them up on the USB HID guide (chapter 10). I also defined “bogus” key codes that I could intercept and do something else with. Most keys on the keyboard can be passed straight through. Others, like the arrow keys, F-keys, quote, asterisk, etc need a little more help since their locations are different than a standard keyboard. I also hacked together to ability to detect a modifier key (shift, control, etc) along with another key (from the keypad library). The resulting code isn’t pretty but I think it’s easy enough to follow. It’s included below for your amusement.

This project is far from perfect but it’s a start.


#include <Keypad.h>
#include <UsbKeyboard.h>

// Define keys that are missing from UsbKeyboard.h
#define KEY_ESCAPE  41
#define KEY_DELETE 42
#define KEY_TAB 43
#define KEY_MINUS 45
#define KEY_EQUAL   46
#define KEY_LEFTBRACKET 47
#define KEY_RIGHTBRACKET 48
#define KEY_BACKSLASH 49
#define KEY_SEMICOLON 51
#define KEY_SINGLE_QUOTE 52
#define KEY_BACKTICK 53
#define KEY_COMMA   54
#define KEY_PERIOD  55
#define KEY_SLASH   56
#define KEY_INSERT  73
#define KEY_HOME    74
#define KEY_PAGEUP 75
#define KEY_PAGEDOWN 78
#define KEY_RIGHTARROW 79
#define KEY_LEFTARROW 80
#define KEY_DOWNARROW 81
#define KEY_UPARROW 82
#define KEY_AT      206

// Bogus key codes, intercepted in code below
#define KEY_PLUS 249
#define LEFT_SHIFT 250
#define RIGHT_SHIFT 251
#define COMMODORE 252
#define CONTROL 253
#define KEY_COLON 254
#define KEY_STAR 255

const byte ROWS = 8;
const byte COLS = 8;
byte mod = 0;

// Define the Keymap
char keys[ROWS][COLS] = {
 {KEY_DELETE, KEY_ENTER, KEY_RIGHTARROW, KEY_F7, KEY_F1, KEY_F3, KEY_F5, KEY_DOWNARROW},
 {KEY_3, KEY_W, KEY_A, KEY_4, KEY_Z, KEY_S, KEY_E, LEFT_SHIFT},
 {KEY_5, KEY_R, KEY_D, KEY_6, KEY_C, KEY_F, KEY_T, KEY_X},
 {KEY_7, KEY_Y, KEY_G, KEY_8, KEY_B, KEY_H, KEY_U, KEY_V},
 {KEY_9, KEY_I, KEY_J, KEY_0, KEY_M, KEY_K, KEY_O, KEY_N},
 {KEY_PLUS, KEY_P, KEY_L, KEY_MINUS, KEY_PERIOD, KEY_COLON, KEY_TAB, KEY_COMMA},
 {KEY_PAGEDOWN, KEY_STAR, KEY_SEMICOLON, KEY_HOME, RIGHT_SHIFT, KEY_EQUAL, KEY_BACKSLASH, KEY_SLASH},
 {KEY_1, KEY_BACKTICK, CONTROL, KEY_2, KEY_SPACE, COMMODORE, KEY_Q, KEY_ESCAPE}
};
byte colPins[COLS] = {4,5,6,7,8,9,10,11};
byte rowPins[ROWS] = {12,0,14,15,16,17,18,19};

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
}

void loop()
{
  UsbKeyboard.update();
  mod = 0;

  // Kludge, find activate modifiers
  // control   [7][2]
  // commodore [7][5]
  pinMode(rowPins[7], OUTPUT);
  digitalWrite(rowPins[7], LOW);
  if (digitalRead(colPins[2]) == LOW) { mod = mod | MOD_CONTROL_LEFT; }
  if (digitalRead(colPins[5]) == LOW) { mod = mod | MOD_ALT_LEFT; }
  pinMode(rowPins[7], INPUT);
  digitalWrite(rowPins[7], HIGH);

  // left shift[1][7]
  pinMode(rowPins[1], OUTPUT);
  digitalWrite(rowPins[1], LOW);
  if (digitalRead(colPins[7]) == LOW) { mod = mod | MOD_SHIFT_LEFT; }
  pinMode(rowPins[1], INPUT);
  digitalWrite(rowPins[1], HIGH);
  
  // right shift[6][4]
  pinMode(rowPins[6], OUTPUT);
  digitalWrite(rowPins[6], LOW);
  if (digitalRead(colPins[4]) == LOW) { mod = mod | MOD_SHIFT_RIGHT; }
  pinMode(rowPins[6], INPUT);
  digitalWrite(rowPins[6], HIGH);
  
  if (mod == 6) {
    UsbKeyboard.sendKeyStroke(0, mod); // This works, but sends 3-4 times. :(
    return;
  }

  char key = kpd.getKey();
  if (key) {
    switch (key) {
      case KEY_STAR:
        UsbKeyboard.sendKeyStroke(KEY_8, MOD_SHIFT_LEFT);
        break;
      case KEY_AT:
        UsbKeyboard.sendKeyStroke(KEY_2, MOD_SHIFT_LEFT);
        break;
      case KEY_PLUS:
        UsbKeyboard.sendKeyStroke(KEY_EQUAL, MOD_SHIFT_LEFT);
        break;
      case KEY_COLON:
        UsbKeyboard.sendKeyStroke(KEY_SEMICOLON, MOD_SHIFT_LEFT);
        break;
      default:
        if (mod == MOD_SHIFT_LEFT || mod == MOD_SHIFT_RIGHT) {
          if (key == KEY_2) { key = KEY_SINGLE_QUOTE; } // "
          if (key == KEY_7) { key = KEY_SINGLE_QUOTE; mod = 0; } // '
          if (key == KEY_6) { key = KEY_7; } // &
          if (key == KEY_9) { key = KEY_0; } // )
          if (key == KEY_8) { key = KEY_9; } // (
          if (key == KEY_DOWNARROW) { key = KEY_UPARROW; mod = 0; }
          if (key == KEY_RIGHTARROW) { key = KEY_LEFTARROW; mod = 0; }
          if (key == KEY_F1) { key = KEY_F2; mod = 0; }
          if (key == KEY_F3) { key = KEY_F4; mod = 0; }
          if (key == KEY_F5) { key = KEY_F6; mod = 0; }
          if (key == KEY_F7) { key = KEY_F8; mod = 0; }
        }
        UsbKeyboard.sendKeyStroke(key, mod);
        break;
    }
  }
}

Converting standard joysticks to wireless infrared for Amiga CDTV and Chameleon 64

The Chameleon 64 is a great cartridge. With each release of the firmware, new features are being unlocked. Recently, the Minimig core was ported to the Chameleon 64 which means you can now have a fully emulated Amiga that fits in the palm of your hand.

To play games using a joystick, you need a CDTV infrared (IR) remote. They are still available for purchase here and here but it would take a few weeks for it to arrive.

I wanted to see if it’s possible to convert a standard joystick to wireless IR communications. I know it can be done– I’ve had some experience using Arduino’s to communicate over IR with a vintage LED sign I have. I reverse engineered the original protocol by using the original remote to the sign. That project taught me a lot.

In this case, I don’t have the remote. So I asked on the forum and got a response from the programmer of the Chameleon IR code with all the info I needed (Thanks Peter!).

This version uses an original Nintendo NES game pad for the joystick but this could be easily changed to support a standard 9-pin Commodore/Amiga/Atari style joystick. The gamepad is connected to the Arduino and decoded into button presses. It then transmits it via infrared signals to the Chameleon. The code uses the Arduino-IRremote library with additions (included) for the CDTV remote type added.

Download CDTV IR Remote