My history with a Commodore 64

Before December 1983 my dad had written a letter to my mum which my grandmother read aloud which mentioned something to the effect of, “I’d like to buy Iain and Robyn a Commodore 64”.

The excitement of me going, “YES!” and then realizing maybe that wasn’t the response I should have given, “Maybe not? Is it okay?”. You could see the confusion in my voice because my parents did not have the smoothest of divorces and messaging was really confusing about us hating him yet still having a relationship with him.

I digress, December arrived and he visited taking us to the University of Guelph to introduce us to some of his colleagues and their work, going for meals. I really felt in those days, Dad was doing his best and making an effort to do what he could to inspire us and be a Dad.

I was too excited, after all, I was 10 years old and I was about to get an amazing computer! I had already experienced an Apple ][ and Commodore PETs at school; being exposed to UNIX and an IBM 5150 PC at my mum’s work; and friends had a Commodore VIC-20.

We drove to Guelph one late afternoon, went to a Zellers, and pick up a Commodore 64, a 1701 monitor, 1541 disk drive and all with, i think, a free VIC Desk! I think we also got Music Maker as well, so we weren’t left without something to try.

Those early days of not understanding how to load programs from the Commodore 64 and the 1541 – I remember my Grandfather and Uncle figuring it out; to getting my first joystick – a Suncom Slik Stick, and games Radar Rate Race and Jupiter Lander for my birthday.

I did so much with this computer

  • I played and copied many games
  • I did hours of homework using Easy Script and geoWrite
  • I spent a lot of time entering programs from magazines, though I admit to not writing too many of my own designed programs in those days. Compute!’s Gazett, Ahoy!, Commodore Magazine, Commodore Power/Play – I had to get them monthly from WH Smith – thanks mum! I actually still have these though I am considering passing these on to the University of Toronto’s Computing Archive
  • To help me learn the piano, I’d using music sequencing software to help learn timing of notes and such – this definitely inspired my music project, in the future and my comfort in programming analogue synthesizers
  • I did a lot of BBSing once I picked up a Commodore 1670 modem, around, I think, 1987

Mum actually used Paperclip to help type a book for one of the profs she worked with, rather than typing it out on Wordperfect on her work PC. I don’t remember how long the Commodore 64 was in her bedroom or at her office, but it certainly was a significant amount of time.

I made a number of friendships over the Commodore 64 – Paul and his dad too me to my first World of Commodore in December 1984. Paul gave me some of the first games – Ghostbusters, Pole Position and Frantic Freddie.

I’d learn about Super Snapshot cartridges, fast loaders, how bad Commodore printers were – thanks to my uncle for helping to purchase a Commodore 1526 printer that I used for many years to print out assignments; until I purchased a Xetec Supergrapics Jr and a Star NX-1000 Rainbow printer – the first piece of computer hardware I saved up for and purchased with summer work money.

I even bought a 1764 REU which, in some respects was a waste of money, though it really did speed up GEOS which I used VERY extensively for homework assignments.

I still have that Commodore 64, the 1541 disk drive, the REU and every disk I ever owned. Gone is the monitor, the VIC Desk, . The last time I turned it on was last year, and unfortunately, I think one of the PLA chips died as I was backing up my disks to an SD card – Pi1541 for the backup win!

Thankfully, the World of Commodore is still going and I was able to purchase a replacement PLA chip – that I still have yet to install. I will likely do that in the coming weeks.

While the TS 1000 was the first computer I owned, the main computer I used was this Commodore 64. It was a workhorse for me from 1983 to 1990 when I picked up a Commodore Amiga 500.

Such a powerful computer at the time, and I realize now there was so much more I could have learned, especially with electronics and the user port. I’d have loved to have had a second disk drive, a second phone line into the house and run a BBS. I actually did run one for a short time period, but off the main phone line. My grandmother was not pleased with me. LOL!

Still, I did push that computer and loved every minute of it.

Arduino Projects

I really like the Arduino and Raspberry Pi Pico platforms. I’ve learned a fair bit about electronics, microprocessors and even AI.

Embedded systems are, in deed, quite different from writing software for a traditional computer.

Despite the number of boards I have, and my familiarity with writing code for Arduino and MicroPython, I have only a handful of projects that I’ve put together.

Pong – Built off a Pico and a Pimoroni Unicorn Pack, I created a simple two person Pong game. Total retro fun, in colour, too!

Christmas Ornaments

  • Arduino Version – I don’t recall which LED panel I used, but I think it was this NeoPixel Shield from AdaFruit, and an Arduino Uno. Using C++ and the AdaFruit NeoPixel Library I wrote a number of animations and messages that would be displayed. A bit bulky to hang on a tree, it’s still a lovely addition as a techy ornament
  • Raspberry Pi Pico – Using a Pimoroni Pico Display Pack, I created an ornament that cycled through 10 images with snow ‘falling” on the pictures. Users could also stop the animation and go through the pictures individually with the buttons.

You can find the code in my personal Git repository for Picopong and the Christmas ornaments.

I have one other project to complete – the Tapduino as a replacement tape drive for a Commodore 64 or Vic 20. Bring on those T64 files!

I may also look into creating a tool to display details about soil in the garden.

Christmas 2016 Ornament – Using Arduino

I created a Christmas ornament using an Arduino Uno and an 8×5 NeoPixel Shield.

In short it,

  • Displays one of seven messages randomly
  • Displays a set of bars that animates – Based on this thread
  • Displays a star that moves and cycles colours – Based on this tutorial

The code is, essentially, C and REALLY easy to develop, and the APIs from AdaFruit make this wicked fast to get code up and running quickly.  The language used for Arduino actually is based on Processing, but also accepts C and C++.

The Libraries used are:

  • AdaFruit GFX Library
  • AdaFruit NeoMatrix
  • AdaFruit NeoPixel

Here is the code:

#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
 
// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
// NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
// Position of the FIRST LED in the matrix; pick two, e.g.
// NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
// NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
// rows or in vertical columns, respectively; pick one or the other.
// NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
// in the same order, or alternate lines reverse direction; pick one.
// See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)

#define PIN 6
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(6, 8, PIN,
 NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT +
 NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
 NEO_GRB + NEO_KHZ800);


// Global Variables
// matrix_x, y used to drive the size of the LED matrix
// text_pass used to change text colours after each pass
// starpos used to position the star when switching to different colours
// starpos_incdec is used to move the star back and forth based on the boundaries of the matrix
// rand_messages is used to randmize the messge that is shown
// text_colours is an array of colours to use for the text, star_rgb used for star color values, star_colour used to drive the actual colour of the star
int matrix_x = matrix.width();
int matrix_y = matrix.height();
int text_pass = 0;
int starpos = 0;
boolean starpos_incdec = 1;
int rand_messages = 0;
unsigned int star_rgb[3] = {255,255,255};
uint16_t star_colour = matrix.Color(star_rgb[0], star_rgb[1], star_rgb[2]);
const uint16_t text_colours[] = {matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(255, 255, 0),matrix.Color(0, 0, 255), matrix.Color(255, 0, 255), matrix.Color(0, 255, 255), matrix.Color(255, 255, 255)};

 // Merry Christmas Message 
String myMessages[]={"Merry Christmas", "You've been naughty", "Krampus is here", "Ho Ho Ho!", "Happy Holidays","Meet me under the mistletoe", "Home for the Holidays"}; 
int myMessagesSizes[]={-98,-120,-98,-80,-95,-170,-140};
// Code
void setup() 
{
 Serial.begin(9600);
 matrix.begin();
 matrix.setTextWrap(false);
 matrix.setBrightness(6);
 matrix.setTextColor(text_colours[0]);
}

void update_star()
{
 // Future code fix - Make dynamic based on matrix_x and matrix_y
 // In short, if the star hits the Y boundaries, move back
 if (starpos+4 == 7) { starpos_incdec = 0; } 
 if (starpos == 0) { starpos_incdec = 1; } 

 // Clear screen, draw star
 matrix.fillScreen(0);
 star_colour = matrix.Color(star_rgb[1], star_rgb[0], star_rgb[2]);
 matrix.drawLine(0, starpos, 4, starpos+4, star_colour);
 matrix.drawLine(0, starpos+4, 4, starpos, star_colour);
 matrix.drawLine(0, starpos+2, 4, starpos+2, star_colour);
 matrix.drawLine(2, starpos, 2, starpos+4, star_colour); 
 matrix.show(); 
 delay(1);
}

void color_morph(unsigned int* value, int get_brighter)
{
 // Updates the colour through updating the refence. 
 // Get brighter flag increments/decrements
 for (int i = 0; i < 255; i++)
 {
 if (get_brighter)
 (*value)--;
 else
 (*value)++;

 update_star();
 }
 if (starpos_incdec) { starpos++; } else { starpos--; } 
}

void rowColorWipe(uint32_t c1, uint32_t c2, uint32_t c3, uint16_t wait) 
{
 // Borrowed code to draw green, white and red bars
 // Clear screen
 matrix.fillScreen(0);

 // Draw the bars
 for(int j=0; j<2; j++) {
 for(int q=0; q<6; q++){
 for(int y=0; y <= matrix.height() + 10; y=y+6) {
 matrix.drawLine(0, y+q-11, 5, y+q-6, c3);
 matrix.drawLine(0, y+q-10, 5, y+q-5, c1);
 matrix.drawLine(0, y+q-9, 5, y+q-4, c1);
 matrix.drawLine(0, y+q-8, 5, y+q-3, c3);
 matrix.drawLine(0, y+q-7, 5, y+q-2, c2);
 matrix.drawLine(0, y+q-6, 5, y+q-1, c2);
 }
 matrix.show();
 delay(wait);
 }
 }
}

void loop()
{
 // The main Arduino loop
 // Displays the christmas message, then the Christmas Wrapping bars, and then the star animation
 // Easier to have the message scroll here rather than using a separate method/function
 
 // Clears screen and sets message
 matrix.fillScreen(0);
 matrix.setCursor(matrix_x, 0); 
 matrix.print(myMessages[rand_messages]);
 // matrix.print(F("Merry Christmas")); // If using a single message

 // Enter this only if the message has been fully displayed. It's displayed by moving the cursor
 if(--matrix_x <= myMessagesSizes[rand_messages]) {
 // Reset message scroll
 matrix_x = matrix.width();
 matrix.setCursor(matrix_x, 0);

 // Christmas Wrapping bars
 rowColorWipe(matrix.Color(255, 0, 0), matrix.Color(255, 255, 255), matrix.Color(0, 255, 0), 500);

 // Cycle through the star colours
 color_morph(&star_rgb[0], 1); // transition to red
 color_morph(&star_rgb[1], 1); // transition to yellow
 color_morph(&star_rgb[0], 0); // transition to green 
 color_morph(&star_rgb[2], 1); // transition to aqua 
 color_morph(&star_rgb[0], 1); // transition to white
 color_morph(&star_rgb[1], 0); // transition to violet
 color_morph(&star_rgb[0], 0); // transition to blue
 color_morph(&star_rgb[2], 0); // transition to black (all off)
 
 if(++text_pass >= 8) text_pass = 0;
 matrix.setTextColor(text_colours[text_pass]);
 rand_messages = random(0,7); // Random number between 0 and 7 (n-1)
 } 
 matrix.show();
 delay(100); 
}