Switchless ROMS - M...
 
Notifications
Clear all

Switchless ROMS - Melius board using Arduino?

6 Posts
2 Users
1 Likes
48 Views
(@tien-that-ton)
Active Member Customer
Joined: 11 months 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: 5 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: 11 months 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: 5 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: 5 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: 11 months ago
Posts: 3
Topic starter  

Thanks.


   
ReplyQuote
Share: