Reset Display Mod

Nothing beats the thrill of modding a mod!! The Switchless Reset Mod (link), in which an Arduino Pro Mini is used to do Warm or Cold Resets (Soft and Hard Resets), needed a little upgrade… Instead of just resetting the C64, I wanted to keep track of how many Warm and Cold Resets I had done since the last power-on and it should (of course) be shown on a nice blue LCD display. Why you may ask? Well, because it’s cheap (4$ including shipping from China), it’s blue and I had no better things to do with it…

I ordered a so-called 16×2 I2C serial LCD display (16 characters and 2 lines). The LCD has a small black interface board attached to the back. This small circuit allows to interface with the Arduino using just 2 wires (+ 2 wires for Ground and +5V). Without the small PCB, a whole bunch of wires have to be connected to the Arduino. There is also a small potentiometer on the black interface board for adjusting the contrast of the display.

I used the instructions on how to use the display here (link) and added my own display code to the original code for the Switchless Reset Mod (link). It’s important to exchange the standard LiquidCrystal library with the one found here (link) – otherwise it won’t work!  The final source code can be found at the end of this post.

The display was connected to the Arduino Pro Mini using these four pins: VCC (Vcc line), GND (GND line), SDA (analog A4 pin) and SCL (analog A5 pin). I tested it in my ZIF socket modded Commodore 64C (link).When the Commodore 64 is turned on, this is what is written on the display. Pressing the RESTORE button for less than 2 seconds will tell the user to press longer! Pressing the RESTORE button for 2-4 seconds, the system will do a Warm Reset.

Pressing the RESTORE button for 4-10 seconds, the machine will do a Cold Reset. If the RESTORE button is pressed for more than 10 seconds,will let the user know to let go of the RESTORE key a little faster. After any reset the total number of Cold and Warm Resets, since the last power-on, is displayed.

A little video showing the mod in action.

Here is the source code for the Reset Display Mod. Double click to enable plain text view of the code. Changing the text written on the display should be pretty straight forward 🙂 Please use it at your own risk!

/*
  Version 1.01 (updated October 18th 2017)

  Purpose:
  Switchless warm/cold reset system for a Commodore 64
  Show number of warm/cold resets on LCD display

  Warm reset:
  Clears any BASIC program stored in memory and resets the computer back to the opening blue screen

  Cold reset:
  If an extended pulse is applied to the /EXROM line at reset time, any machine language program will 
  clear and resets the computer back to the opening blue screen.

  Function:
  If RESTORE button is pressed for 2-4 seconds -> RESET line LOW (Warm Reset)
  If RESTORE button is pressed for 4-10 seconds -> RESET line LOW & /EXROM line LOW for 300ms extra (Cold Reset)
  If RESTORE button is pressed for >10 seconds -> nothing happens
   
  Hardware:
  Arduino Pro Mini, ATmega328 (5V, 16MHz)
  16x2 I2C LCD display

  Disclamier:
  Tested on an Assy 250469 short board-> assumed to work across all motherboard versions
  Use at your own risk!

  Updates:
  Pinmode of the RESET and /EXROM lines are held as INPUT until requested to pull them LOW during Reset. This is to
  keep the Arduino from constantly driving the reset line and to support to support cartridges like the Final Cartridge III.

  By MtnBuffalo/breadbox64.com 2017
*/

// Libraries
#include <Wire.h>                     // allows communication with I2C devices
#include <LiquidCrystal_I2C.h>        // controls liquid crystal displays (LCD)

// Constants
const int RESTORE_button = A0;        // pin A0 is connected to the RESTORE button (analog input pin)
const int RESET_line = 3;             // pin 3 is connected to the RESET line (digital output pin)
const int EXROM_line = 4;             // pin 4 is connected to the /EXROM line of the PLA (digital output pin)
const int press_time_warm = 2000;     // time in milliseconds before a warm reset is initiated
const int press_time_cold = 4000;     // time in milliseconds before a cold reset is initiated
const int voltageValue = 100;         // ADC value that will trigger the timer (voltages less than 0.5V) -> RESTORE pushed  
const int warm_lcd = 0;               // for printing on the LCD
const int cold_lcd = 1;               // for printing on the LCD
const int too_short_press = 2;        // for printing on the LCD that the RESTORE press was too short
const int too_long_press = 3;         // for printing on the LCD that the RESTORE press was too long

// Variables
unsigned long RESTORE_press_time = 0; // the time the RESTORE button is being pressed in milliseconds
unsigned long StartTime = 0;          // first time stamp for calculating RESTORE_press_time
int firstpress = 1;                   // test if the RESTORE button has been pressed
int analogValue;                      // ADC value (0-1023) read from the RESTORE button
int coldResets = 0;                   // total number of Cold Resets since the computer was turned on
int warmResets = 0;                   // total number of Warm Resets since the computer was turned on

// Functions
int debounce();                       // debounce function to get ADC value (analogValue)
void lcd_print(int);                  // print function for the LCD display

// Objects
// connect SDA line from the LCD to A4 on the Ardunio (analog input pin)
// connect SCL line from the LCD to A5 on the Ardunio (analog input pin)
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // initialize LCD

void setup()
{
  // initialize digital pins
  pinMode(RESET_line, INPUT);         // digital pin 3 on the Arduino Pro Mini - set as OUTPUT before cold/warm resets
  pinMode(EXROM_line, INPUT);         // digital pin 4 on the Arduino Pro Mini - set as OUTPUT before cold reset
  
  digitalWrite(RESET_line, HIGH);     // initial RESET_line state
  digitalWrite(EXROM_line, HIGH);     // initial EXROM_line state
  
  pinMode(RESTORE_button, INPUT);     // analog pin A0 on the Arduino Pro Mini
  analogReference(DEFAULT);           // setting the analog reference to 5V
 
  // initialize LCD with start-up text
  lcd.begin(16, 2);                   // set up the LCD's number of rows and columns & turn on backlight
  lcd.setCursor(0, 0);                // set cursor to first character (column=0) on the top line (line=0)
  lcd.print("Display Mod 2016");      // print standard text on the LCD 
  lcd.setCursor(0, 1);                // set cursor to first character (column=0) on the bottom line (line=1)
  lcd.print("Warm:   Cold:");         // print standard text to bottom line of LCD
  lcd.setCursor(5, 1);                // set cursor to 6th character (column=5) on the bottom line (line=1) 
  lcd.print(warmResets);              // print value
  lcd.setCursor(13, 1);               // set cursor to the 14th character (column=13) on the bottom line (line=1) 
  lcd.print(coldResets);              // print value
}

void loop() 
{
  analogValue = debounce();                       // call debounce function to get average ADC value
  if(analogValue < voltageValue)                  // checks if the RESTORE button has been pressed
  {
        // initiate RESTORE push timer
        if(firstpress == 1)                       
        {
          firstpress = 0;                   
          StartTime = millis();                   // first time stamp
          delay(2);                               // make sure that RESTORE_press_time will become > 0 milliseconds
        }
     RESTORE_press_time = millis() - StartTime;   // variable holds total time RESTORE is pressed
   }
   else if(firstpress == 0) firstpress = 1;       // RESTORE button has been released
   
  // Warm reset (cancel reset if RESTORE is pushed < press_time_warm -> 2 seconds)
  if (firstpress == 1 && RESTORE_press_time > press_time_warm && RESTORE_press_time < press_time_cold)
  {
    pinMode(RESET_line, OUTPUT);      // set as output to pull down the reset line
    digitalWrite(RESET_line, LOW);    // anode side of CR5 diode (Assy 250469) or pin 3 of User Port (Assy 250425) LOW
    delay(200);
    digitalWrite(RESET_line, HIGH);   // reset RESET_line
    RESTORE_press_time = 0;           // reset timer
    pinMode(RESET_line, INPUT);       // reset the RESET line
    warmResets++;                     // update counter for the LCD display
    lcd_print(warm_lcd);              // call print function for updating number of resets
  }

  // Cold reset (cancel reset if RESTORE is pushed > 10 seconds)
  else if (firstpress == 1 && RESTORE_press_time > press_time_cold && RESTORE_press_time < 10000) 
  {
    pinMode(RESET_line, OUTPUT);      // set as output to pull down the reset line
    pinMode(EXROM_line, OUTPUT);      // set as OUTPUT to pull down the /EXROM line
    digitalWrite(RESET_line, LOW);    // anode side of CR5 diode (Assy 250469) or pin 3 of User Port (Assy 250425) LOW
    digitalWrite(EXROM_line, LOW);    // /EXROM line of the PLA LOW
    delay(200);
    digitalWrite(RESET_line, HIGH);   // reset RESET_line
    delay(300);
    digitalWrite(EXROM_line, HIGH);   // reset EXROM_line

    RESTORE_press_time = 0;           // reset timer
    pinMode(RESET_line, INPUT);       // reset the RESET line
    pinMode(EXROM_line, INPUT);       // reset the /EXROM line

    coldResets++;                     // update counter for the LCD display
    lcd_print(cold_lcd);              // call print function for updating number of reset
  }

  // print to LCD that the RESTORE press was too short but longer than a key stroke
  else if (firstpress == 1 && RESTORE_press_time > 500 && RESTORE_press_time < press_time_warm) 
  {
    RESTORE_press_time = 0;           // reset timer
    lcd_print(too_short_press);
  }
  // print to LCD that the RESTORE was pressed for too long
  else if (firstpress == 1 && RESTORE_press_time > 10000)
  {
    RESTORE_press_time = 0;           // reset timer
    lcd_print(too_long_press);
  }
}

// Debounce function to filter transistions/noise of the analog reading
int debounce()
{
  int x, meanADC, sum = 0;
  for (int i = 0; i < 5; i++){                          // reads ADC value from pin A0 5 times
     delay(5);                                          // debounce for 25 ms total
     sum += analogRead(RESTORE_button);
  }
  x = sum / 5;                                          // mean ADC value  
 (x < voltageValue) ? (meanADC = x) : (meanADC = 1023); // if/else check - has RESTORE been pushed?
  return meanADC;                                       // return mean ADC value to main loop
}

// print function for updating the number of resets
void lcd_print(int y)
{
  lcd.clear();                      // clear the LCD
  lcd.setCursor(0, 0);              // set cursor to first character (column=0) on the top line (line=0)
  if (y == 0)
  {
    lcd.print(" Warm reset...  ");  
  }
  else if (y == 1)
  {
    lcd.print(" Cold reset...  ");
  }
  else if (y == 2)
  {
    lcd.print(" Press longer!!!");
  }
  else if (y == 3)
  {
    lcd.print("Let go faster!!!");
  }
    
  delay (4000);
  lcd.setCursor(0, 0);              // set cursor to first character (column=0) on the top line (line=0)
  lcd.print("Display Mod 2016");    // re-print standard text on the LCD 
  lcd.setCursor(0, 1);              // set cursor to first character (column=0) on the bottom line (line=1)
  lcd.print("Warm:   Cold:");       // re-print standard text to bottom line of LCD
  lcd.setCursor(5, 1);              // set cursor to 6th character (column=5) on the bottom line (line=1) 
  lcd.print(warmResets);            // print value
  lcd.setCursor(13, 1);             // set cursor to the 14th character (column=13) on the bottom line (line=1) 
  lcd.print(coldResets);            // print value
  return;
}

 

© breadbox64.com 2016

1 thought on “Reset Display Mod”

  1. Code updated: To keep the Arduino from constantly driving the Reset line, the pinmode has been changed to INPUT by default. Whenever the Arduino is requested to pull the Reset line to LOW (for Warm or Cold resets), the pinmode is changed to OUTPUT. After the reset, the pinmode is set back to INPUT again.

Leave a Comment