teensy.ino 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295
  1. /*
  2. * Copyright (c) 2009 Andrew Brown
  3. * Copyright (c) 2018 rcombs
  4. *
  5. * Permission is hereby granted, free of charge, to any person
  6. * obtaining a copy of this software and associated documentation
  7. * files (the "Software"), to deal in the Software without
  8. * restriction, including without limitation the rights to use,
  9. * copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the
  11. * Software is furnished to do so, subject to the following
  12. * conditions:
  13. * The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  17. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22. * OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. #include "crc_table.h"
  25. #ifdef TEENSYDUINO
  26. #include <BufferedPrint.h>
  27. #include <FreeStack.h>
  28. #include <RingBuf.h>
  29. #include <SdFat.h>
  30. #include <sdios.h>
  31. #include <SdFatConfig.h>
  32. #include <MinimumSerial.h>
  33. #include <DMAChannel.h>
  34. #include <EEPROM.h>
  35. #ifndef PIT_LTMR64H
  36. #define PIT_LTMR64H (*(volatile uint32_t *)0x400370E0) // PIT Upper Lifetime Timer Register
  37. #define PIT_LTMR64L (*(volatile uint32_t *)0x400370E4) // PIT Lower Lifetime Timer Register
  38. #endif
  39. #define SD_CONFIG SdSpiConfig(SDCARD_SS_PIN, SHARED_SPI, SD_SCK_MHZ(50))
  40. #define STATUS_PIN 13
  41. #define POWER_PIN 32
  42. #define VI_PIN 35
  43. #define FIELD_PIN 36
  44. #define HAVE_EEPROM
  45. #define HAVE_GPIO_COMMANDS
  46. #define SERIAL_BAUD_RATE 115200
  47. #define N64_PIN 38
  48. #define SNES_LATCH_PIN 3
  49. #define SNES_CLOCK_PIN 4
  50. #define SNES_DATA_PIN 5
  51. #define N64_HIGH (CORE_PIN38_DDRREG &= ~CORE_PIN38_BITMASK) //digitalWriteFast(N64_PIN, HIGH)
  52. #define N64_LOW (CORE_PIN38_DDRREG |= CORE_PIN38_BITMASK) //digitalWriteFast(N64_PIN, LOW)
  53. #define N64_QUERY ((CORE_PIN38_PINREG & CORE_PIN38_BITMASK) ? 1 : 0) //digitalReadFast(N64_PIN)
  54. #define LED_HIGH (CORE_PIN13_PORTSET = CORE_PIN13_BITMASK) //digitalWriteFast(STATUS_PIN, HIGH)
  55. #define LED_LOW (CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK) //digitalWriteFast(STATUS_PIN, LOW)
  56. #define SERIAL_TIMEOUT_US 5000000
  57. #define DISABLE_N64_INTERRUPT() \
  58. volatile uint32_t *config = portConfigRegister(N64_PIN); \
  59. uint32_t oldConfig = *config; \
  60. *config &= ~0x000F0000;
  61. #define ENABLE_N64_INTERRUPT() \
  62. *config = oldConfig;
  63. #endif
  64. #define INPUT_BUFFER_SIZE 2048 // Multiples of 512 are ideal since we can read 256*4/2 = 512 bytes at once.
  65. // 512 bytes is an optimization for reading the sd card and skips using another buffer.
  66. #define INPUT_BUFFER_UPDATE_TIMEOUT 10 // 10 ms
  67. #define MICRO_CYCLES (F_CPU / 1000000)
  68. #ifdef F_BUS
  69. #define MICRO_BUS_CYCLES (F_BUS / 1000000ULL)
  70. #endif
  71. #define MAX_CMD_LEN 4096
  72. #define MAX_LOOP_LEN 10240
  73. typedef enum Console {
  74. N64 = 0,
  75. NES = 1,
  76. SNES = 2,
  77. } Console;
  78. static Console console = N64;
  79. static bool skippingInput = false;
  80. static String inputString;
  81. static char n64_raw_dump[36]; // maximum recv is 1+2+32 bytes + 1 bit
  82. // n64_raw_dump does not include the command byte. That gets pushed into
  83. // n64_command:
  84. static int n64_command;
  85. // bytes to send to the 64
  86. // maximum we'll need to send is 33, 32 for a read request and 1 CRC byte
  87. static unsigned char output_buffer[33];
  88. // Simple switch buffer. (If buffer A fails to load while buffer B is in use,
  89. // we still okay, and will try again next loop)
  90. static unsigned char inputBuffer[INPUT_BUFFER_SIZE];
  91. static size_t bufferEndPos;
  92. static volatile size_t bufferPos;
  93. static volatile bool bufferHasData;
  94. static void updateInputBuffer();
  95. static bool hold = false;
  96. static bool finished = false;
  97. static SdFile tasFile;
  98. //static unsigned int progressPos = 0;
  99. static String filename;
  100. static unsigned long numFrames = 0, curFrame = 0;
  101. static int edgesRead = 0;
  102. static int incompleteCommand = 0;
  103. static int firstEdgeTime = 0;
  104. static int secondEdgeTime = 0;
  105. static volatile unsigned long viCount = 0;
  106. static SdFs sd;
  107. #ifdef SNES_DATA_PIN
  108. static uint16_t currentSnesFrame;
  109. static uint32_t frameDuration = 0;
  110. #endif
  111. static uint64_t finalTime = 0;
  112. static uint64_t lastFrameTime = 0;
  113. static int doLoop = 0;
  114. #define N_SER_BUFS 16
  115. #define SER_BUF_SIZE 256
  116. static char serBuffer[N_SER_BUFS][SER_BUF_SIZE] = {0};
  117. static volatile bool bufHasData[N_SER_BUFS] = {0};
  118. static void n64Interrupt();
  119. template<class T> void lockedPrintln(const T& input)
  120. {
  121. noInterrupts();
  122. Serial.println(input);
  123. interrupts();
  124. }
  125. template<class A, class B> void lockedPrintln(const A& a, const B& b)
  126. {
  127. noInterrupts();
  128. Serial.print(a);
  129. Serial.println(b);
  130. interrupts();
  131. }
  132. #ifdef ARM_DWT_CYCCNT
  133. static void startTimer()
  134. {
  135. ARM_DWT_CYCCNT = 0;
  136. }
  137. static uint32_t readTimer()
  138. {
  139. return ARM_DWT_CYCCNT;
  140. }
  141. static uint32_t readAndResetTimer()
  142. {
  143. return __atomic_exchange_n(&ARM_DWT_CYCCNT, 0, __ATOMIC_SEQ_CST);
  144. }
  145. #endif
  146. #ifdef PIT_LTMR64H
  147. static bool timer64Started = false;
  148. static void start64Timer()
  149. {
  150. // turn on PIT
  151. SIM_SCGC6 |= SIM_SCGC6_PIT;
  152. __asm__ volatile("nop"); // solves timing problem on Teensy 3.5
  153. PIT_MCR = 0x00;
  154. // Timer 1
  155. PIT_TCTRL1 = 0x0; // disable timer 1 and its interrupts
  156. PIT_LDVAL1 = 0xFFFFFFFF; // setup timer 1 for maximum counting period
  157. PIT_TCTRL1 |= PIT_TCTRL_CHN; // chain timer 1 to timer 0
  158. PIT_TCTRL1 |= PIT_TCTRL_TEN; // start timer 1
  159. // Timer 0
  160. PIT_TCTRL0 = 0; // disable timer 0 and its interrupts
  161. PIT_LDVAL0 = 0xFFFFFFFF; // setup timer 0 for maximum counting period
  162. PIT_TCTRL0 = PIT_TCTRL_TEN; // start timer 0
  163. timer64Started = true;
  164. }
  165. static uint64_t read64Timer()
  166. {
  167. if (!timer64Started)
  168. return 0;
  169. uint64_t current_uptime = (uint64_t)PIT_LTMR64H << 32;
  170. current_uptime = current_uptime + PIT_LTMR64L;
  171. return 0xffffffffffffffffull - current_uptime;
  172. }
  173. #endif
  174. static size_t getNextRegion(size_t& size) {
  175. size_t currentPos = bufferPos;
  176. if ((currentPos == bufferEndPos || (currentPos == 0 && bufferEndPos == INPUT_BUFFER_SIZE)) && bufferHasData) {
  177. size = 0;
  178. return 0;
  179. }
  180. size_t ret = bufferEndPos;
  181. if (ret == INPUT_BUFFER_SIZE)
  182. ret = 0;
  183. size = INPUT_BUFFER_SIZE - ret;
  184. if (ret < currentPos)
  185. size = currentPos - ret;
  186. return ret;
  187. }
  188. void initBuffers()
  189. {
  190. bufferEndPos = 0;
  191. bufferPos = 0;
  192. bufferHasData = false;
  193. }
  194. static bool overflowed = 0;
  195. void logFromISR(const char *fmt, ...)
  196. {
  197. int i;
  198. for (i = 0; i < N_SER_BUFS && bufHasData[i]; i++);
  199. if (i >= N_SER_BUFS) {
  200. overflowed = 1;
  201. return;
  202. }
  203. char* buf = &serBuffer[i][0];
  204. size_t size = SER_BUF_SIZE - 1;
  205. va_list ap;
  206. va_start(ap, fmt);
  207. vsnprintf(buf, size, fmt, ap);
  208. va_end(ap);
  209. bufHasData[i] = 1;
  210. overflowed = 0;
  211. #ifdef ISR_LOG_CB
  212. ISR_LOG_CB();
  213. #endif
  214. }
  215. static void advanceBuffer(long bytes)
  216. {
  217. curFrame++;
  218. #ifdef PIT_LTMR64H
  219. lastFrameTime = read64Timer();
  220. #endif
  221. if (curFrame == numFrames) {
  222. logFromISR("C:%f",
  223. #ifdef MICRO_BUS_CYCLES
  224. lastFrameTime / (double)(MICRO_BUS_CYCLES * 1000 * 1000)
  225. #else
  226. double(0.)
  227. #endif
  228. );
  229. finished = true;
  230. finalTime = lastFrameTime;
  231. }
  232. size_t pos = bufferPos + bytes;
  233. if (pos == bufferEndPos) {
  234. if (hold)
  235. return;
  236. bufferHasData = false;
  237. bufferPos = pos;
  238. return;
  239. }
  240. if (pos >= INPUT_BUFFER_SIZE)
  241. pos = 0;
  242. bufferPos = pos;
  243. }
  244. static size_t appendInputs(const String& data)
  245. {
  246. size_t totalWritten = 0;
  247. size_t writeLen = 0;
  248. do {
  249. size_t dataLeft = data.length() - totalWritten;
  250. size_t writePos = getNextRegion(writeLen);
  251. if (writeLen > dataLeft)
  252. writeLen = dataLeft;
  253. if (writeLen) {
  254. memcpy(inputBuffer + writePos, data.c_str() + totalWritten, writeLen);
  255. totalWritten += writeLen;
  256. noInterrupts();
  257. finished = false;
  258. bufferEndPos = writePos + writeLen;
  259. bufferHasData = true;
  260. interrupts();
  261. }
  262. } while (writeLen > 0);
  263. return totalWritten;
  264. }
  265. static void emitList(const String& path)
  266. {
  267. SdFile dir;
  268. if (!dir.open(&sd, path.c_str(), O_READ)) {
  269. Serial.println(F("E:Failed to open requested directory"));
  270. return;
  271. }
  272. dir.rewind();
  273. SdFile listFile;
  274. while (listFile.openNext(&dir)) {
  275. char name[256];
  276. listFile.getName(name, sizeof(name));
  277. lockedPrintln("A:", name);
  278. listFile.close();
  279. }
  280. dir.close();
  281. }
  282. void logFrame(const unsigned char *dat, size_t count, size_t num)
  283. {
  284. #define LOG_FRAME_START "F:%u %f %lu"
  285. #define LOG_FRAME_BYTE " %hhx"
  286. #define LOG_FRAME_END " %lu %i %s"
  287. #ifdef PIT_LTMR64H
  288. #define LOG_TIME (read64Timer() / (double)(MICRO_BUS_CYCLES * 1000 * 1000))
  289. #else
  290. #define LOG_TIME (double)0.
  291. #endif
  292. #define LOG_FRAME_START_ARGS num, LOG_TIME, viCount
  293. #define LOG_FRAME_END_ARGS numFrames, overflowed, filename.c_str()
  294. if (count == 4)
  295. logFromISR(LOG_FRAME_START LOG_FRAME_BYTE LOG_FRAME_BYTE LOG_FRAME_BYTE LOG_FRAME_BYTE LOG_FRAME_END,
  296. LOG_FRAME_START_ARGS, dat[0], dat[1], dat[2], dat[3], LOG_FRAME_END_ARGS);
  297. else if (count == 2)
  298. logFromISR(LOG_FRAME_START LOG_FRAME_BYTE LOG_FRAME_BYTE LOG_FRAME_END,
  299. LOG_FRAME_START_ARGS, dat[0], dat[1], LOG_FRAME_END_ARGS);
  300. else if (count == 1)
  301. logFromISR(LOG_FRAME_START LOG_FRAME_BYTE LOG_FRAME_END,
  302. LOG_FRAME_START_ARGS, dat[0], LOG_FRAME_END_ARGS);
  303. #ifdef FRAME_CB
  304. FRAME_CB(dat, count);
  305. #endif
  306. }
  307. #ifdef HAVE_GPIO_COMMANDS
  308. static bool setPinMode(const String& cmd)
  309. {
  310. if (cmd.length() < 3)
  311. return false;
  312. if (cmd[1] != ':')
  313. return false;
  314. int pinNumber = cmd.substring(2).toInt();
  315. if (cmd[0] == 'I')
  316. pinMode(pinNumber, INPUT);
  317. else if (cmd[0] == 'O')
  318. pinMode(pinNumber, OUTPUT);
  319. else if (cmd[0] == 'U')
  320. pinMode(pinNumber, INPUT_PULLUP);
  321. else if (cmd[0] == 'D')
  322. pinMode(pinNumber, INPUT_PULLDOWN);
  323. else
  324. return false;
  325. return true;
  326. }
  327. static bool writePin(const String& cmd)
  328. {
  329. if (cmd.length() < 3)
  330. return false;
  331. if (cmd[1] != ':')
  332. return false;
  333. int pinNumber = cmd.substring(2).toInt();
  334. if (cmd[0] == '0')
  335. digitalWrite(pinNumber, LOW);
  336. else if (cmd[0] == '1')
  337. digitalWrite(pinNumber, HIGH);
  338. else
  339. return false;
  340. return true;
  341. }
  342. #endif
  343. #ifdef POWER_PIN
  344. static bool setPower(const String& cmd)
  345. {
  346. if (cmd.length() < 1)
  347. return false;
  348. if (cmd[0] == '0') {
  349. digitalWrite(POWER_PIN, LOW);
  350. } else if (cmd[0] == '1') {
  351. viCount = 0;
  352. timer64Started = 0;
  353. digitalWrite(POWER_PIN, HIGH);
  354. } else {
  355. return false;
  356. }
  357. return true;
  358. }
  359. #endif
  360. static bool setLoop(const String& cmd)
  361. {
  362. if (cmd.length() < 1)
  363. return false;
  364. if (cmd[0] == '0') {
  365. doLoop = 0;
  366. } else if (cmd[0] == '1') {
  367. doLoop = 1;
  368. } else {
  369. return false;
  370. }
  371. return true;
  372. }
  373. void setupConsole()
  374. {
  375. if (console == N64) {
  376. #ifdef N64_PIN
  377. attachInterrupt(N64_PIN, n64Interrupt, FALLING);
  378. #endif
  379. } else if (console == NES || console == SNES) {
  380. #ifdef SNES_LATCH_PIN
  381. attachInterrupt(SNES_LATCH_PIN, snesLatchInterrupt, RISING);
  382. attachInterrupt(SNES_CLOCK_PIN, snesClockInterrupt, RISING);
  383. #endif
  384. }
  385. }
  386. static bool setConsole(const String& cmd)
  387. {
  388. if (cmd == "N64")
  389. console = N64;
  390. else if (cmd == "NES")
  391. console = NES;
  392. else if (cmd == "SNES")
  393. console = SNES;
  394. else
  395. return false;
  396. setupConsole();
  397. return true;
  398. }
  399. String hextobin(const String& hex)
  400. {
  401. String ret;
  402. ret.reserve((hex.length() + 1) / 2);
  403. // mapping of ASCII characters to hex values
  404. static const uint8_t map[] = {
  405. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
  406. 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
  407. 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // @ABCDEFG
  408. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // HIJKLMNO
  409. };
  410. for (size_t pos = 0; pos < hex.length(); pos += 2) {
  411. size_t idx0 = ((uint8_t)hex[pos] & 0x1F) ^ 0x10,
  412. idx1 = ((uint8_t)hex[pos + 1] & 0x1F) ^ 0x10;
  413. ret += (char)((map[idx0] << 4) | map[idx1]);
  414. }
  415. return ret;
  416. }
  417. static SdFile writeFile;
  418. static void appendData(const String& data) {
  419. if (writeFile.write(data.c_str(), data.length()) == data.length())
  420. Serial.println("AP:OK");
  421. else
  422. Serial.println("AP:NAK");
  423. }
  424. static void waitForIdle(unsigned us)
  425. {
  426. LED_HIGH;
  427. N64_HIGH;
  428. startTimer();
  429. int lastReset = 0;
  430. while (readTimer() - lastReset < us * MICRO_CYCLES && readTimer() < us * MICRO_CYCLES * 4) {
  431. if (!N64_QUERY)
  432. lastReset = readTimer();
  433. }
  434. LED_LOW;
  435. }
  436. static String basename(const String& path) {
  437. int pos = path.lastIndexOf('/');
  438. if (pos < 0)
  439. return path;
  440. return path.substring(pos + 1);
  441. }
  442. static bool openTAS(const String& path) {
  443. char signature[4];
  444. int version;
  445. Serial.write("M:");
  446. Serial.println(path);
  447. // Open the file for reading:
  448. Serial.print(F("L:Opening file '"));
  449. Serial.print(path);
  450. Serial.println(F("'..."));
  451. Serial.flush();
  452. if (tasFile.isOpen())
  453. tasFile.close();
  454. // Error check
  455. if (!tasFile.open(&sd, path.c_str(), O_READ)) {
  456. Serial.println(F("E:Error in opening file"));
  457. return false;
  458. }
  459. // Open header
  460. if (tasFile.read(signature, 4) != 4 || tasFile.read(&version, 4) != 4) {
  461. tasFile.close();
  462. Serial.println(F("E:Failed to read signature"));
  463. return false;
  464. }
  465. // Validate file signature
  466. if (memcmp(signature, "M64\x1A", 4) != 0) {
  467. Serial.println(F("E:m64 signature invalid"));
  468. tasFile.close();
  469. return false;
  470. }
  471. // Print version
  472. Serial.print(F("L:M64 Version: "));
  473. Serial.println(version);
  474. Serial.flush();
  475. tasFile.seekSet(0x018);
  476. // Open header
  477. uint32_t newNumFrames;
  478. if (tasFile.read(&newNumFrames, 4) != 4) {
  479. tasFile.close();
  480. Serial.println(F("E:Failed to read frame count"));
  481. return false;
  482. }
  483. // Get header size
  484. switch(version) {
  485. case 1:
  486. case 2:
  487. tasFile.seekSet(0x200);
  488. break;
  489. case 3:
  490. tasFile.seekSet(0x400);
  491. break;
  492. default:
  493. // Unknown version
  494. Serial.println(F("E:unknown M64 version"));
  495. tasFile.close();
  496. return false;
  497. }
  498. // Final check
  499. if (!tasFile.available()) {
  500. Serial.println(F("E:No input data found in file"));
  501. tasFile.close();
  502. return false;
  503. }
  504. newNumFrames = min(newNumFrames, (tasFile.fileSize() - tasFile.curPosition()) / 4);
  505. Serial.write("N:");
  506. Serial.println(newNumFrames);
  507. Serial.flush();
  508. // Wait for the line to go idle, then begin listening
  509. /*
  510. for (int idle_wait=32; idle_wait>0; --idle_wait) {
  511. if (!N64_QUERY) {
  512. idle_wait = 32;
  513. }
  514. }*/
  515. noInterrupts();
  516. finished = false;
  517. initBuffers();
  518. curFrame = 0;
  519. numFrames = newNumFrames;
  520. console = N64;
  521. filename = basename(path);
  522. interrupts();
  523. setupConsole();
  524. #ifdef POWER_PIN
  525. if (doLoop)
  526. setPower("1");
  527. #endif
  528. return true;
  529. }
  530. static void updateInputBuffer() {
  531. if (finished || !tasFile.isOpen())
  532. return;
  533. // Check for file end
  534. if (!tasFile.available()) {
  535. tasFile.close();
  536. return;
  537. }
  538. size_t availableSize;
  539. size_t writePos = getNextRegion(availableSize);
  540. // Optimized chunk reads
  541. if ((availableSize < 512 && (writePos % 512) == 0) || !availableSize)
  542. return;
  543. int readBytes = tasFile.read(inputBuffer + writePos, availableSize);
  544. if (readBytes <= 0) {
  545. lockedPrintln(F("W:Failed to read next inputs from file. (This is recoverable)"));
  546. return;
  547. }
  548. noInterrupts();
  549. bufferEndPos = writePos + readBytes;
  550. bufferHasData = true;
  551. interrupts();
  552. }
  553. /**
  554. * Complete copy and paste of gc_send, but with the N64
  555. * pin being manipulated instead.
  556. */
  557. static void n64_send(unsigned char *buffer, char length, bool wide_stop)
  558. {
  559. unsigned long target;
  560. LED_HIGH;
  561. N64_LOW;
  562. startTimer();
  563. for (int i = 0; i < length * 8; i++) {
  564. char bit = (buffer[i >> 3] >> (7 - (i & 7))) & 1;
  565. target = MICRO_CYCLES * (3 - bit * 2);
  566. while (readTimer() < target);
  567. N64_HIGH;
  568. while (readTimer() < MICRO_CYCLES * 4);
  569. N64_LOW;
  570. startTimer();
  571. }
  572. target = MICRO_CYCLES * (1 + wide_stop);
  573. while (readTimer() < target);
  574. N64_HIGH;
  575. startTimer();
  576. while (!N64_QUERY && readTimer() < MICRO_CYCLES * 4);
  577. LED_LOW;
  578. }
  579. /**
  580. * Waits for an incomming signal on the N64 pin and reads the command,
  581. * and if necessary, any trailing bytes.
  582. * 0x00 is an identify request
  583. * 0x01 is a status request
  584. * 0x02 is a controller pack read
  585. * 0x03 is a controller pack write
  586. *
  587. * for 0x02 and 0x03, additional data is passed in after the command byte,
  588. * which is also read by this function.
  589. *
  590. * All data is raw dumped to the n64_raw_dump array, 1 bit per byte, except
  591. * for the command byte, which is placed all packed into n64_command
  592. */
  593. static void get_n64_command()
  594. {
  595. int bitcount = 8;
  596. n64_command = 0;
  597. char newByte = 0;
  598. LED_HIGH;
  599. #define FAIL_TIMEOUT {\
  600. if (readTimer() >= MICRO_CYCLES * 10) {\
  601. n64_command = -1; \
  602. goto fail; \
  603. } \
  604. }\
  605. edgesRead = 0;
  606. for (int i = 1; i <= bitcount; i++) {
  607. while (!N64_QUERY)
  608. FAIL_TIMEOUT;
  609. long lowTime = readAndResetTimer();
  610. if (!edgesRead)
  611. firstEdgeTime = lowTime;
  612. edgesRead++;
  613. while (N64_QUERY)
  614. FAIL_TIMEOUT;
  615. long highTime = readAndResetTimer();
  616. if (edgesRead == 1)
  617. secondEdgeTime = highTime;
  618. edgesRead++;
  619. char bit =
  620. #ifdef USE_COMPARE_ABSOLUTE
  621. (highTime >= MICRO_CYCLES * 2)
  622. #else
  623. (lowTime < highTime)
  624. #endif
  625. ;
  626. newByte <<= 1;
  627. newByte |= bit;
  628. if (i == 8) {
  629. n64_command = newByte;
  630. switch (newByte) {
  631. case (0x03):
  632. // write command
  633. // we expect a 2 byte address and 32 bytes of data
  634. bitcount += 272; // 34 bytes * 8 bits per byte
  635. //Serial.println("command is 0x03, write");
  636. break;
  637. case (0x02):
  638. // read command 0x02
  639. // we expect a 2 byte address
  640. bitcount += 16;
  641. //Serial.println("command is 0x02, read");
  642. break;
  643. case (0x00):
  644. case (0x01):
  645. default:
  646. // get the last (stop) bit
  647. break;
  648. }
  649. } else if (!(i & 7)) {
  650. n64_raw_dump[(i >> 3) - 1] = newByte;
  651. }
  652. }
  653. // Wait for the stop bit
  654. while (!N64_QUERY)
  655. FAIL_TIMEOUT;
  656. startTimer();
  657. while (readTimer() < MICRO_CYCLES * 2);
  658. fail:
  659. incompleteCommand = newByte;
  660. LED_LOW;
  661. }
  662. static void n64Interrupt()
  663. {
  664. noInterrupts();
  665. unsigned char data, addr;
  666. int ticksSinceLast = readAndResetTimer();
  667. bool haveFrame;
  668. #ifdef DISABLE_N64_INTERRUPT
  669. DISABLE_N64_INTERRUPT();
  670. #endif
  671. // Wait for incoming 64 command
  672. // this will block until the N64 sends us a command
  673. get_n64_command();
  674. // 0x00 is identify command
  675. // 0x01 is status
  676. // 0x02 is read
  677. // 0x03 is write
  678. switch (n64_command)
  679. {
  680. case 0x00:
  681. case 0xFF:
  682. // identify
  683. // mutilate the output_buffer array with our status
  684. // we return 0x050001 to indicate we have a rumble pack
  685. // or 0x050002 to indicate the expansion slot is empty
  686. //
  687. // 0xFF I've seen sent from Mario 64 and Shadows of the Empire.
  688. // I don't know why it's different, but the controllers seem to
  689. // send a set of status bytes afterwards the same as 0x00, and
  690. // it won't work without it.
  691. output_buffer[0] = 0x05;
  692. output_buffer[1] = 0x00;
  693. output_buffer[2] = 0x01;
  694. n64_send(output_buffer, 3, 1);
  695. logFromISR("P:%ld", viCount);
  696. viCount = 0;
  697. #ifdef PIT_LTMR64H
  698. start64Timer();
  699. #endif
  700. break;
  701. case 0x01:
  702. haveFrame = (!finished && bufferHasData);
  703. // If the TAS is finished, there's nothing left to do.
  704. if (haveFrame)
  705. memcpy(output_buffer, inputBuffer + bufferPos, 4);
  706. else
  707. memset(output_buffer, 0, 4);
  708. // blast out the pre-assembled array in output_buffer
  709. n64_send(output_buffer, 4, 1);
  710. logFrame(output_buffer, 4, curFrame + (haveFrame ? 1 : 0));
  711. if (!haveFrame)
  712. break;
  713. // update input buffer and make sure it doesn't take too long
  714. /*Serial.print(F("Pos: "));
  715. Serial.print(bufferPos);
  716. Serial.print(F(" Data: "));
  717. Serial.println(inputBuffer[bufferPos]);*/
  718. advanceBuffer(4);
  719. // while (Serial.availableForWrite() && readTimer() < 10 * 1000 * MICRO_CYCLES && N64_QUERY);
  720. /* if (!finished)
  721. curPos = (curFrame * screen.width()) / numFrames;
  722. screen.fill(255,0,0);
  723. while (progressPos < curPos) {
  724. screen.point(progressPos++, screen.height() - 1);
  725. }
  726. screen.fill(255,255,255);*/
  727. break;
  728. case 0x02:
  729. // A read. If the address is 0x8000, return 32 bytes of 0x80 bytes,
  730. // and a CRC byte. this tells the system our attached controller
  731. // pack is a rumble pack
  732. // Assume it's a read for 0x8000, which is the only thing it should
  733. // be requesting anyways
  734. memset(output_buffer, 0x80, 32);
  735. output_buffer[32] = 0xB8; // CRC
  736. n64_send(output_buffer, 33, 1);
  737. logFromISR("L:Got a read, what?");
  738. //Serial.println("It was 0x02: the read command");
  739. break;
  740. case 0x03:
  741. // A write. we at least need to respond with a single CRC byte. If
  742. // the write was to address 0xC000 and the data was 0x01, turn on
  743. // rumble! All other write addresses are ignored. (but we still
  744. // need to return a CRC)
  745. // decode the first data byte (fourth overall byte), bits indexed
  746. // at 24 through 31
  747. data = 0;
  748. data |= (n64_raw_dump[16] != 0) << 7;
  749. data |= (n64_raw_dump[17] != 0) << 6;
  750. data |= (n64_raw_dump[18] != 0) << 5;
  751. data |= (n64_raw_dump[19] != 0) << 4;
  752. data |= (n64_raw_dump[20] != 0) << 3;
  753. data |= (n64_raw_dump[21] != 0) << 2;
  754. data |= (n64_raw_dump[22] != 0) << 1;
  755. data |= (n64_raw_dump[23] != 0);
  756. // get crc byte, invert it, as per the protocol for
  757. // having a memory card attached
  758. output_buffer[0] = crc_repeating_table[data] ^ 0xFF;
  759. // send it
  760. n64_send(output_buffer, 1, 1);
  761. logFromISR("L:Got a write, what?");
  762. // end of time critical code
  763. // was the address the rumble latch at 0xC000?
  764. // decode the first half of the address, bits
  765. // 8 through 15
  766. addr = 0;
  767. addr |= (n64_raw_dump[0] != 0) << 7;
  768. addr |= (n64_raw_dump[1] != 0) << 6;
  769. addr |= (n64_raw_dump[2] != 0) << 5;
  770. addr |= (n64_raw_dump[3] != 0) << 4;
  771. addr |= (n64_raw_dump[4] != 0) << 3;
  772. addr |= (n64_raw_dump[5] != 0) << 2;
  773. addr |= (n64_raw_dump[6] != 0) << 1;
  774. addr |= (n64_raw_dump[7] != 0);
  775. //Serial.println("It was 0x03: the write command");
  776. //Serial.print("Addr was 0x");
  777. //Serial.print(addr, HEX);
  778. //Serial.print(" and data was 0x");
  779. //Serial.println(data, HEX);
  780. break;
  781. case -1:
  782. if (finished)
  783. break;
  784. logFromISR("W:RTO; %d read; b:%02hhx; %d since; %d/%d to 1/2", edgesRead, incompleteCommand, ticksSinceLast, firstEdgeTime, secondEdgeTime);
  785. if (curFrame > 100)
  786. logFromISR("D:timeout");
  787. waitForIdle(1000);
  788. break;
  789. default:
  790. if (finished)
  791. break;
  792. logFromISR("W:Unknown; %d read; b:%02hhx; %d since; %d/%d to 1/2", edgesRead, n64_command, ticksSinceLast, firstEdgeTime, secondEdgeTime);
  793. if (curFrame > 100)
  794. logFromISR("D:inval");
  795. waitForIdle(1000);
  796. break;
  797. }
  798. #ifdef ENABLE_N64_INTERRUPT
  799. ENABLE_N64_INTERRUPT();
  800. #endif
  801. interrupts();
  802. }
  803. #ifdef SNES_DATA_PIN
  804. static void snesWriteBit()
  805. {
  806. digitalWrite(SNES_DATA_PIN, (currentSnesFrame & 0x8000) ? LOW : HIGH);
  807. if (currentSnesFrame & 0x8000)
  808. LED_HIGH;
  809. else
  810. LED_LOW;
  811. currentSnesFrame <<= 1;
  812. currentSnesFrame |= 1;
  813. }
  814. static void snesLatchInterrupt()
  815. {
  816. noInterrupts();
  817. int haveFrame = (!finished && bufferHasData);
  818. int len = (console == SNES) ? 2 : 1;
  819. if (!haveFrame) {
  820. unsigned char logBuf[2] = {0, 0};
  821. currentSnesFrame = 0;
  822. logFrame(logBuf, len, curFrame + 1);
  823. } else {
  824. if (console == NES) {
  825. currentSnesFrame = (inputBuffer[bufferPos] << 8) | 0xFF;
  826. } else {
  827. currentSnesFrame = (inputBuffer[bufferPos] << 8) | inputBuffer[bufferPos + 1];
  828. }
  829. logFrame(inputBuffer + bufferPos, len, curFrame + 1);
  830. }
  831. snesWriteBit();
  832. if (readTimer() >= frameDuration) {
  833. startTimer();
  834. if (haveFrame)
  835. advanceBuffer(len);
  836. }
  837. interrupts();
  838. }
  839. static void snesClockInterrupt()
  840. {
  841. noInterrupts();
  842. snesWriteBit();
  843. interrupts();
  844. }
  845. #endif
  846. #ifdef HAVE_EEPROM
  847. static void setEEPROM(const String& cmd)
  848. {
  849. // Write terminator first, so we won't overread (by much) if we die early
  850. EEPROM.write(cmd.length(), 0);
  851. unsigned j = 0;
  852. for (unsigned i = 0; i < cmd.length(); i++, j++) {
  853. if (cmd[i] == '\\' && cmd[i + 1] == 'n') {
  854. EEPROM.write(j, '\n');
  855. i++;
  856. } else if (cmd[i] == '\\' && cmd[i + 1] == '\\') {
  857. EEPROM.write(j, '\\');
  858. i++;
  859. } else {
  860. EEPROM.write(j, cmd[i]);
  861. }
  862. }
  863. EEPROM.write(j, 0);
  864. lockedPrintln("L:Finished writing to EEPROM:", cmd.c_str());
  865. }
  866. #endif
  867. static void handleCommand(const String& cmd)
  868. {
  869. if (cmd.startsWith("M:")) {
  870. openTAS(cmd.substring(2));
  871. } else if (cmd.startsWith("O:")) {
  872. //dummy
  873. } else if (cmd.startsWith("L:")) {
  874. emitList(cmd.substring(2));
  875. } else if (cmd.startsWith("MK:")) {
  876. lockedPrintln("MK:", sd.mkdir(cmd.substring(3).c_str()));
  877. } else if (cmd.startsWith("CR:")) {
  878. if (writeFile.isOpen()) {
  879. writeFile.close();
  880. }
  881. if (writeFile.open(&sd, cmd.substring(3).c_str(), O_WRITE | O_CREAT | O_TRUNC)) {
  882. lockedPrintln("CR:OK");
  883. } else {
  884. lockedPrintln("CR:NAK");
  885. }
  886. } else if (cmd.startsWith("AP:")) {
  887. appendData(hextobin(cmd.substring(3)));
  888. } else if (cmd.startsWith("IN:")) {
  889. size_t len = appendInputs(hextobin(cmd.substring(3)));
  890. lockedPrintln("IN:", len);
  891. } else if (cmd.startsWith("HL:")) {
  892. hold = cmd[3] == '1';
  893. } else if (cmd.startsWith("CL:")) {
  894. writeFile.close();
  895. lockedPrintln("CL:OK");
  896. #ifdef HAVE_GPIO_COMMANDS
  897. } else if (cmd.startsWith("PM:")) {
  898. setPinMode(cmd.substring(3));
  899. } else if (cmd.startsWith("DW:")) {
  900. writePin(cmd.substring(3));
  901. #endif
  902. #ifdef POWER_PIN
  903. } else if (cmd.startsWith("PW:")) {
  904. setPower(cmd.substring(3));
  905. #endif
  906. } else if (cmd.startsWith("SC:")) {
  907. setConsole(cmd.substring(3));
  908. #ifdef HAVE_EEPROM
  909. } else if (cmd.startsWith("WN:")) {
  910. setEEPROM(cmd.substring(3));
  911. #endif
  912. } else if (cmd.startsWith("LO:")) {
  913. setLoop(cmd.substring(3));
  914. } else {
  915. lockedPrintln("E:Unknown CMD:", cmd.c_str());
  916. }
  917. }
  918. static void handleChar(int newChar)
  919. {
  920. if (newChar == '\n') {
  921. if (skippingInput)
  922. Serial.println("E:Skipped too-long line");
  923. else
  924. handleCommand(inputString);
  925. inputString = "";
  926. skippingInput = false;
  927. } else if (inputString.length() > MAX_CMD_LEN) {
  928. skippingInput = true;
  929. } else {
  930. inputString += (char)newChar;
  931. }
  932. }
  933. static void inputLoop()
  934. {
  935. int newChar;
  936. int charsRead = 0;
  937. while ((newChar = Serial.read()) != -1 && (charsRead++ <= MAX_LOOP_LEN))
  938. handleChar(newChar);
  939. }
  940. static void mainLoop()
  941. {
  942. updateInputBuffer();
  943. // Record if it took longer than expected
  944. /*updateTime = readTimer();
  945. if (updateTime > 1000 * MICRO_CYCLES) {
  946. Serial.print(F("Input buffer update took too long ("));
  947. Serial.print(updateTime / MICRO_CYCLES);
  948. Serial.println(F(" us)"));
  949. }*/
  950. }
  951. #ifdef HAVE_EEPROM
  952. static void runEEPROM()
  953. {
  954. int i = 0;
  955. while (i < 1000) {
  956. int c = EEPROM.read(i);
  957. if (!c)
  958. break;
  959. handleChar(c);
  960. i++;
  961. }
  962. if (i)
  963. handleChar('\n');
  964. }
  965. #endif
  966. void loop()
  967. {
  968. inputLoop();
  969. mainLoop();
  970. #ifdef HAVE_EEPROM
  971. if (doLoop) {
  972. static bool isClearing = false;
  973. uint64_t curTime = read64Timer();
  974. if ((finished && timer64Started && (curTime - finalTime) > (MICRO_BUS_CYCLES * 1000 * 1000 * (isClearing ? 1 : 30)))
  975. // || (timer64Started && (curTime - lastFrameTime) > (MICRO_BUS_CYCLES * 1000 * 1000 * 30))
  976. ) {
  977. setPower("0");
  978. while ((read64Timer() - curTime) < (MICRO_BUS_CYCLES * 1000 * 1000 * 2));
  979. isClearing = !isClearing;
  980. if (isClearing)
  981. openTAS("clear.m64");
  982. else
  983. runEEPROM();
  984. }
  985. }
  986. #endif
  987. bool first = true;
  988. bool gotData = false;
  989. do {
  990. int i = 0;
  991. gotData = false;
  992. if (first) {
  993. for (; i < N_SER_BUFS; i++) {
  994. if (!bufHasData[i])
  995. break;
  996. else
  997. gotData = true;
  998. }
  999. }
  1000. first = false;
  1001. for (; i < N_SER_BUFS; i++) {
  1002. if (bufHasData[i]) {
  1003. #ifdef LOG_CB
  1004. LOG_CB(&serBuffer[i][0]);
  1005. #endif
  1006. Serial.println(&serBuffer[i][0]);
  1007. bufHasData[i] = 0;
  1008. Serial.flush();
  1009. gotData = true;
  1010. }
  1011. }
  1012. } while (gotData);
  1013. }
  1014. #ifdef VI_PIN
  1015. static void viInterrupt()
  1016. {
  1017. viCount++;
  1018. }
  1019. #endif
  1020. void printSDError(const char* msg) {
  1021. (void)msg;
  1022. if (sd.sdErrorCode()) {
  1023. if (sd.sdErrorCode() == SD_CARD_ERROR_ACMD41) {
  1024. Serial.println("Try power cycling the SD card.");
  1025. }
  1026. printSdErrorSymbol(&Serial, sd.sdErrorCode());
  1027. Serial.print(", ErrorData: 0X");
  1028. Serial.println(sd.sdErrorData(), HEX);
  1029. }
  1030. }
  1031. void setup()
  1032. {
  1033. #ifdef ARM_DEMCR
  1034. ARM_DEMCR |= ARM_DEMCR_TRCENA;
  1035. #endif
  1036. #ifdef ARM_DWT_CTRL
  1037. ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
  1038. #endif
  1039. startTimer();
  1040. #ifdef SERIAL_TIMEOUT_US
  1041. while (readTimer() > MICRO_CYCLES * 1000 * 1000);
  1042. #endif
  1043. Serial.begin(SERIAL_BAUD_RATE);
  1044. #ifdef SERIAL_TIMEOUT_US
  1045. while (!Serial) {
  1046. if (readTimer() > MICRO_CYCLES * SERIAL_TIMEOUT_US) {
  1047. doLoop = 1;
  1048. break;
  1049. }
  1050. } // wait for serial port to connect. Needed for native USB port only
  1051. Serial.print(F("L:Serial init timer exited: doLoop="));
  1052. Serial.println(doLoop);
  1053. #endif
  1054. LED_HIGH;
  1055. // Status LED
  1056. #ifdef STATUS_PIN
  1057. digitalWrite(STATUS_PIN, LOW);
  1058. pinMode(STATUS_PIN, OUTPUT);
  1059. #endif
  1060. // Configure controller pins
  1061. #ifdef N64_PIN
  1062. pinMode(N64_PIN, INPUT_PULLUP);
  1063. digitalWrite(N64_PIN, LOW);
  1064. #endif
  1065. #ifdef SNES_LATCH_PIN
  1066. pinMode(SNES_LATCH_PIN, INPUT);
  1067. pinMode(SNES_CLOCK_PIN, INPUT);
  1068. pinMode(SNES_DATA_PIN, OUTPUT);
  1069. digitalWrite(SNES_DATA_PIN, LOW);
  1070. #endif
  1071. // Power
  1072. #ifdef POWER_PIN
  1073. digitalWrite(POWER_PIN, LOW);
  1074. pinMode(POWER_PIN, OUTPUT);
  1075. #endif
  1076. // VI pulse
  1077. #ifdef VI_PIN
  1078. pinMode(VI_PIN, INPUT);
  1079. attachInterrupt(VI_PIN, viInterrupt, FALLING);
  1080. #endif
  1081. // Let the controller pins interrupt anything else
  1082. #ifdef IRQ_PORTC
  1083. NVIC_SET_PRIORITY(IRQ_PORTC, 0);
  1084. #endif
  1085. // Let the VI pin interrupt anything other than controller pins
  1086. // NVIC_SET_PRIORITY(IRQ_PORTC, 16);
  1087. #ifndef SD_CONFIG
  1088. #define SD_CONFIG BUILTIN_SDCARD
  1089. #endif
  1090. // Initialize SD card
  1091. if (!sd.begin(SD_CONFIG)) {
  1092. printSDError("init");
  1093. Serial.println(F("E:SD initialization failed!"));
  1094. return;
  1095. }
  1096. Serial.println(F("L:SD initialization done."));
  1097. // Setup buffer
  1098. initBuffers();
  1099. Serial.println(F("L:Initialization done."));
  1100. #ifdef HAVE_EEPROM
  1101. if (doLoop)
  1102. runEEPROM();
  1103. #endif
  1104. }