Hi,
I have a Melius v1.2 board and it works great.
I would like to use Arduino to switch between kernals / basic and characters, preferably with RGB LED to indicate which ROMS is seleted. Wondering if there is such code available for the Arduino.
Regards
VNMan
Were you thinking of using just a push button to select the next ROM? If so, it would be simple enough to setup, depending on how you want to configure it, the least amount of I/O would be switching the Basic, Kernel and Character all at once. To do this, you would need to setup a variable to keep track of the count, if you're switching them all at once, the max number you would have would be 8, 7 if you're starting at index 0.. Then you would need 3 output lines and every time you press the button, you would increment the count variable and then you would have a case statement that would check the count value and output any of the 8 states;
000
001
010
011
100
101
110
111
You would then connect the pins of each ROM to the outputs on the Arduino so that they all switch together, you would also need some way of resetting the C64 after the switch happens, you could tie another output pin from the Arduino to the Reset line on the CPU and pull it low after the button is pressed and then release it.
If you need help with writing the code I may have some time this weekend but if you have some experience with Arduino then you should be able to accomplish this.
I followed your guide on the switchless that you sell, but using Arduino "Pro Mini". Tried all the codes available on the net, nothing work.
Just wonder if the switch voltage of the ROMs is different here.
Appreciated if you could give me recommendation of Arduino to use and maybe the code if you have time.
Thanks
I should have some time this weekend. I'll post here when I have it ready. Using a Pro Mini should be fine.
Please take a look at the code below. This is a variation I wrote for the Arduino which was originally written by BWACK in mikroC and then rewritten by TEBL to use a single LED. This works exactly like my switchless ROMs utilizing the C64's RESTORE button and RESET signal to allow you to advance to the next ROM automatically after 2 blinks of the LED. It will reset the C64 after 1 blink and anything after 2 blinks will select the ROM in that slot. So 3 blinks is ROM 1, 4 blinks ROM 2, etc.. all the way to ROM 8.
I also made a short video demo so you can see how this works.
#include <EEPROM.h> // Define the Arduino pin numbers for the connections const int restorePin = 3; // RESTORE connected to digital pin 3 (This goes to the C64 RESTORE button) const int redLEDPin = 5; // Red LED connected to digital pin 5 (This goes to the C64 Main Power LED) const int resetPin = 4; // Reset connected to digital pin 4 (This goes to the C64 Reset signal check pin 40 on the CPU) // Address pins connected to digital pins 8, 9, 10 respectively for A13, A14, A15 // These connect to A13, A14, A15 on the middle pins of the ROM jumpers const int addressPins[3] = {8, 9, 10}; enum State { IDLE_STATE, WAIT_RELEASE, ROM_TOGGLE, ROM_SET, RESET }; State state = IDLE_STATE; char cycle = 0; char buttonTimer = 0; char oldButton; char romNo = 0; void setROM(char rom) { // Write the ROM number to the address pins for (int i = 0; i < 3; i++) { digitalWrite(addressPins[i], (rom >> i) & 0x01); } // Save the ROM number to EEPROM at address 0 EEPROM.write(0, rom); } void toggleROM() { romNo = (romNo + 1) & 0x07; // Keep ROM number within 0-7 setROM(romNo); } void resetC64() { digitalWrite(resetPin, LOW); digitalWrite(redLEDPin, !digitalRead(redLEDPin)); // Toggle LED delay(50); digitalWrite(redLEDPin, !digitalRead(redLEDPin)); // Toggle LED delay(200); digitalWrite(resetPin, HIGH); } void blinkLED() { digitalWrite(redLEDPin, !digitalRead(redLEDPin)); delay(100); digitalWrite(redLEDPin, !digitalRead(redLEDPin)); delay(100); } void setLED() { digitalWrite(redLEDPin, HIGH); } void setup() { // Initialize pins pinMode(restorePin, INPUT_PULLUP); pinMode(redLEDPin, OUTPUT); pinMode(resetPin, OUTPUT); // Set address pins as outputs for (int i = 0; i < 3; i++) { pinMode(addressPins[i], OUTPUT); } // Read the last selected ROM from EEPROM romNo = EEPROM.read(0) & 0x07; // Ensure it's within 0-7 // If the EEPROM has invalid data, reset to ROM 0 if (romNo > 7) { romNo = 0; } // Set the initial ROM and reset the C64 setROM(romNo); resetC64(); } void loop() { // Keep the LED on at all times setLED(); // Main state machine switch (state) { case IDLE_STATE: if (!digitalRead(restorePin)) { // Restore button is pressed buttonTimer++; // Wait a bit for debouncing delay(100); } else { if (cycle > 0) { // Button was released state = WAIT_RELEASE; oldButton = 0; buttonTimer = 0; } else { // Button is not pressed, reset the timer buttonTimer = 0; delay(100); } } // Check if the button has been held down long enough if (buttonTimer > 10) { cycle++; buttonTimer = 0; // Blink the LED to indicate the button press blinkLED(); } break; case WAIT_RELEASE: // Act based on how long the button was held switch (cycle) { case 1: state = RESET; break; case 2: state = ROM_TOGGLE; break; case 3: state = ROM_SET; romNo = 1; break; case 4: state = ROM_SET; romNo = 2; break; case 5: state = ROM_SET; romNo = 3; break; case 6: state = ROM_SET; romNo = 4; break; case 7: state = ROM_SET; romNo = 5; break; case 8: state = ROM_SET; romNo = 6; break; case 9: state = ROM_SET; romNo = 7; break; case 10: state = ROM_SET; romNo = 8; break; default: state = RESET; break; } cycle = 0; break; case ROM_TOGGLE: // Toggle the ROM state = RESET; toggleROM(); break; case ROM_SET: // Set the ROM state = RESET; setROM(romNo); break; case RESET: // Perform a reset resetC64(); state = IDLE_STATE; // Return to the idle state break; default: // Should never be reached; if it is, reset the state machine state = IDLE_STATE; break; } }
Thanks.
Nice. I'm waiting for some arduino micro, but my idea is trying to implement this to make a rom change in the 1541 with just pressing a button, so I can get a led color change.
Hi,
I have trying to create a simple Arduino Code for the 1541 Rom Switch.
So basically I want to add to the 1541 a Toggle Button, so with the button I can have 2 states:
- CBM ROM, LED Green ON
- Jiffy DOS, LED Blue ON
So far, keeping it simple, I have this:
#define LED_Green 6 #define LED_Blue 7 #define BUTTON_PIN 8 #define A13 9 #define A14 10 #define RESET 11 void setup() { pinMode(LED_Green, OUTPUT); pinMode(LED_Blue, OUTPUT); pinMode(BUTTON_PIN, INPUT); pinMode (A13, OUTPUT); pinMode (A14, OUTPUT); pinMode (RESET, OUTPUT); } void loop() { if (digitalRead(BUTTON_PIN) == HIGH) { digitalWrite(LED_Green, HIGH); //TURN ON GREEN LED digitalWrite(LED_Blue, LOW); //TURN OF BLUE LED digitalWrite(A13, HIGH); //SELECT ROM1 digitalWrite(A14, LOW); //ROM 2 NOT SELECTED } else { digitalWrite(LED_Green, LOW); //TURN OFF GREEN LED digitalWrite(LED_Blue, HIGH); // TURN ON BLUE LED digitalWrite(A13, LOW); //ROM 1 NOT SELECTED digitalWrite(A14, HIGH); //SELECT ROM 2 } }
What I'm not sure how to manage is the RESET:
- The C64 resets when we INPUT a high to the Reset Line?
- How can I make the Arduino to only send the reset once and not in the loop?
The idea is using the 27C512 with this adapter:
Will appreciate any help, thanks!
Ok, I have completed and simulated the code and is doing what it supose:
#define LED_Green 6 #define LED_Blue 7 #define BUTTON_PIN 8 #define A13 13 #define A14 10 #define RESET 11 int estado, estadoAnt=0; int accion=0; void resetC64() { digitalWrite(RESET, LOW); delay(500); digitalWrite(RESET, HIGH); } void setup() { pinMode(LED_Green, OUTPUT); pinMode(LED_Blue, OUTPUT); pinMode(BUTTON_PIN, INPUT); pinMode (A13, OUTPUT); pinMode (A14, OUTPUT); pinMode (RESET, OUTPUT); if (digitalRead(BUTTON_PIN) == HIGH) { digitalWrite(LED_Green, HIGH); digitalWrite(LED_Blue, LOW); digitalWrite(A13, HIGH); digitalWrite(A14, LOW); resetC64(); } else { digitalWrite(LED_Green, LOW); digitalWrite(LED_Blue, HIGH); digitalWrite(A13, LOW); digitalWrite(A14, HIGH); resetC64(); } } void loop() { estado = digitalRead(BUTTON_PIN); if (estado && !estadoAnt) { accion = 1 -accion; if (accion) { digitalWrite(LED_Green, HIGH); digitalWrite(LED_Blue, LOW); digitalWrite(A13, HIGH); digitalWrite(A14, LOW); resetC64(); } else { digitalWrite(LED_Green, LOW); digitalWrite(LED_Blue, HIGH); digitalWrite(A13, LOW); digitalWrite(A14, HIGH); resetC64(); } } estadoAnt = estado; }
But know I have a question. If I understand correctly, in order to reset we need to GND the RESET line in the C64 right? Is that safe? To me is a circuit short right?