Switchless ROMS - M...
 
Notifications
Clear all

Switchless ROMS - Melius board using Arduino?

9 Posts
3 Users
1 Reactions
747 Views
(@tien-that-ton)
Active Member Customer
Joined: 2 years ago
Posts: 3
Topic starter  

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


   
Quote
(@administrator)
Member Admin
Joined: 6 years ago
Posts: 9
 

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.


   
ReplyQuote
(@tien-that-ton)
Active Member Customer
Joined: 2 years ago
Posts: 3
Topic starter  

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


   
ReplyQuote
(@administrator)
Member Admin
Joined: 6 years ago
Posts: 9
 

I should have some time this weekend. I'll post here when I have it ready. Using a Pro Mini should be fine.


   
ReplyQuote
(@administrator)
Member Admin
Joined: 6 years ago
Posts: 9
 

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.

https://youtu.be/ru4_0S2XN0U

#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;
  }
}

   
ReplyQuote
(@tien-that-ton)
Active Member Customer
Joined: 2 years ago
Posts: 3
Topic starter  

Thanks.


   
ReplyQuote
(@rafael-martinez)
New Member Customer
Joined: 2 years ago
Posts: 4
 

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.


   
ReplyQuote
(@rafael-martinez)
New Member Customer
Joined: 2 years ago
Posts: 4
 

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!

This post was modified 10 months ago by Rafael Martinez

   
ReplyQuote
(@rafael-martinez)
New Member Customer
Joined: 2 years ago
Posts: 4
 

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?


   
ReplyQuote
Share: