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
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.