aboutsummaryrefslogtreecommitdiffhomepage
path: root/Cart_Reader/ST.ino
blob: 4800115eb5328f7c41a2f47bb76c45a882c754a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/******************************************
  SUPER FAMICOM SUFAMI TURBO MODULE
******************************************/
#if (defined(ENABLE_ST) && defined(ENABLE_SNES))

/******************************************
  Menu
*****************************************/
// Sufami Turbo menu items
static const char stMenuItem1[] PROGMEM = "Read cart in Slot A";
static const char stMenuItem2[] PROGMEM = "Read cart in Slot B";
static const char* const menuOptionsST[] PROGMEM = { stMenuItem1, stMenuItem2, FSTRING_RESET };

void stMenu() {
  // Create ST menu with title and 3 options to choose from
  unsigned char mainMenu;
  convertPgm(menuOptionsST, 3);
  mainMenu = question_box(F("Sufami Turbo"), menuOptions, 3, 0);

  // Wait for user choice to come back from the question box menu
  switch (mainMenu) {
    // Read cart in ST slot A
    case 0:
      readSlot(0);
      break;

    // Read cart in ST slot B
    case 1:
      readSlot(1);
      break;

    // Reset
    case 2:
      resetArduino();
      break;
  }
}

/******************************************
   Setup
 *****************************************/
void setup_ST() {
  // Request 5V
  setVoltage(VOLTS_SET_5V);

  // Set cicrstPin(PG1) to Output
  DDRG |= (1 << 1);
  // Output a high signal until we're ready to start
  PORTG |= (1 << 1);
  // Set cichstPin(PG0) to Input
  DDRG &= ~(1 << 0);

  // Set Address Pins to Output
  //A0-A7
  DDRF = 0xFF;
  //A8-A15
  DDRK = 0xFF;
  //BA0-BA7
  DDRL = 0xFF;
  //PA0-PA7
  DDRA = 0xFF;

  // Set Control Pins to Output RST(PH0) CS(PH3) WR(PH5) RD(PH6)
  DDRH |= (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6);
  // Switch RST(PH0) and WR(PH5) to HIGH
  PORTH |= (1 << 0) | (1 << 5);
  // Switch CS(PH3) and RD(PH6) to LOW
  PORTH &= ~((1 << 3) | (1 << 6));
  // Set Refresh(PE5) to Output
  DDRE |= (1 << 5);
  // Switch Refresh(PE5) to LOW (needed for SA-1)
  PORTE &= ~(1 << 5);
  // Set CPU Clock(PH1) to Output
  DDRH |= (1 << 1);
  // Set IRQ(PH4) to Input
  DDRH &= ~(1 << 4);
  // Set expand(PG5) to Input
  DDRG &= ~(1 << 5);
  // Set Data Pins (D0-D7) to Input
  DDRC = 0x00;
  // Unused pins
  // Set wram(PE4) to Output
  DDRE |= (1 << 4);
  // Set pawr(PJ1) to Output
  DDRJ |= (1 << 1);
  // Set pard(PJ0) to Output
  DDRJ |= (1 << 0);

  //Check if Sufami Turbo adapter is inserted
  if (!getHeader(0)) {
    display_Clear();
    println_Msg(F("Sufami Turbo adapter"));
    println_Msg(F("was not found."));
    display_Update();
    wait();
    resetArduino();
  }
}

/******************************************
  ROM Functions
******************************************/
// Verify if 'BANDAI' header is present in specified bank
bool getHeader(unsigned int bank) {
  byte snesHeader[16];
  PORTL = bank;

  // Read first bytes
  for (uint16_t c = 0, currByte = 0; c < 16; c++, currByte++) {
    PORTF = (currByte & 0xFF);
    PORTK = ((currByte >> 8) & 0xFF);
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
    snesHeader[c] = PINC;
  }

  // Format internal name
  buildRomName(romName, &snesHeader[0], 14);

  // Check if 'BANDAI' header is present
  if (strncmp(romName, "BANDAI SFC-ADX", 14) == 0)
    return(1);
  else
    return(0);
} 

// Select the slot to use and detect cart size
void readSlot(bool cartSlot) {
  // Set control
  dataIn();
  controlIn_SNES();
  sd.chdir("/");
  display_Clear();

  if(!cartSlot) {            // Slot A was selected
    if (getHeader(32)) {     // Look for a cart in slot A
      if (getHeader(48))     // Look for mirrored data in slot A
        readRom_ST(32,48);   // Dump 512KB cart
      else                   
        readRom_ST(32,64);   // Dump 1MB cart
    }
    else {
      println_Msg(F("No cart detected in Slot A"));
      display_Update();
      wait();
    }
  }
  else {                      // Slot B was selected
    if (getHeader(64)) {      // Look for a cart in slot B
      if (getHeader(80))      // Look for mirrored data in slot B
        readRom_ST(64,80);    // Dump 512KB cart
      else
        readRom_ST(64,96);    // Dump 1MB cart
    }
    else {
      println_Msg(F("No cart detected in Slot B"));
      display_Update();
      wait();
    }
  }
}

// Read ST rom to SD card
void readRom_ST(unsigned int bankStart, unsigned int bankEnd) {
  // create a new folder to save rom file
  createFolderAndOpenFile("ST", "ROM", "SUFAMI_TURBO", "st");

  // Read specified banks
  readLoRomBanks(bankStart + 0x80, bankEnd + 0x80, &myFile);

  // Close file:
  myFile.close();

  // Compare dump CRC with db values
  compareCRC("st.txt", 0, 1, 0);
  
  println_Msg(FS(FSTRING_EMPTY));
  print_STR(press_button_STR, 1);
  display_Update();
  wait();
}
#endif

//******************************************
// End of File
//******************************************