The porting of the NESBot Play the 'Tool Assisted Speedrun' videos on the real machine(NES). original (with Arduino): http://www.instructables.com/id/NESBot-Arduino-Powered-Robot-beating-Super-Mario-/ Almost same as the original, it need generated Key-input data by emulator with Lua script. See the original instructables' documents to know how to generate data file. BOM: mbed x1 NES x1 NES controller x1 4021(shift registor) x1

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 // - The porting of the NESBot
00004 // original : http://www.instructables.com/id/NESBot-Arduino-Powered-Robot-beating-Super-Mario-/
00005 // 
00006 // ported by Kaoru Shoji : http://mbed.org/users/kshoji
00007 // 
00008 // - Connections:
00009 // a NES, a mbed and a 4021 (shift register) needed.
00010 // 
00011 // for example) AV-FAMICOM(JPY) connector pinout
00012 // 1 LATCH (PL, P/S)    -> mbed's 9 pin
00013 // 2 CLOCK              -> 4021's 10 pin
00014 // 3 VCC                -> 4021's 16 pin
00015 // 4 GND                -> mbed's GND & 4021's 8 pin
00016 // 5 DATA               -> 4021's 3 pin
00017 // 
00018 // - Note:
00019 // The mbed's VCC must be supplied from USB cable.
00020 // If mbed's VCC is supplied from NES VCC, the LATCH signal detection may be failed.
00021 // 
00022 // - How to use:
00023 // 0. Prepare the replay data with FCEUX and Lua script. (Lua script can be downloaded from instructables).
00024 //    The data file needs to be placed into mbed's LocalFileSystem(on the root directory).
00025 // 1. NES power turn off.
00026 // 2. connect mbed to NES, and USB power.
00027 // 3. NES power turn on.
00028 
00029 InterruptIn latchInterrupt(p9); // LATCH signal in
00030 
00031 DigitalOut R(p10); // -> 4021's p1(7)
00032 DigitalOut L(p11); // -> 4021's p2(6)
00033 DigitalOut D(p12); // -> 4021's p3(5)
00034 DigitalOut U(p13); // -> 4021's p4(4)
00035 DigitalOut T(p14); // -> 4021's p5(13)
00036 DigitalOut S(p15); // -> 4021's p6(14)
00037 DigitalOut B(p16); // -> 4021's p7(15)
00038 DigitalOut A(p17); // -> 4021's p8(1)
00039 
00040 // status LEDs
00041 DigitalOut led1(LED1);
00042 DigitalOut led2(LED2);
00043 DigitalOut led3(LED3);
00044 DigitalOut led4(LED4);
00045 
00046 LocalFileSystem local("mbed");
00047 
00048 // Large buffer may cause time rag when file loading.
00049 #define BUFFER_LENGTH (128)
00050 
00051 unsigned char controllerData[BUFFER_LENGTH];
00052 int controllerDataPosition = 0;
00053 
00054 FILE *fp;
00055 long fileLength = 0;
00056 long filePosition = 0;
00057 
00058 volatile bool finished = false;
00059 
00060 void writeButtons() {
00061     unsigned char state = ~controllerData[controllerDataPosition];
00062 
00063     // output to shift register
00064     R = state & 0x80;
00065     L = state & 0x40;
00066     D = state & 0x20;
00067     U = state & 0x10;
00068     T = state & 0x08;
00069     S = state & 0x04;
00070     B = state & 0x02;
00071     A = state & 0x01;
00072 }
00073 
00074 void showLEDs() {
00075     led1 = !U | !D;
00076     led2 = !L | !R;
00077     led3 = !A;
00078     led4 = !B;
00079 }
00080 
00081 void trigger() {
00082     // when P/S Control signal falled(Serial mode)
00083     // read the controller state
00084     writeButtons();
00085     showLEDs();
00086 
00087     filePosition++;
00088     if (filePosition >= fileLength) {
00089         latchInterrupt.fall(0);
00090         finished = true;
00091         return;
00092     }
00093 
00094     controllerDataPosition++;
00095     if (controllerDataPosition >= BUFFER_LENGTH) {
00096         fread(controllerData, 1, BUFFER_LENGTH, fp);
00097         controllerDataPosition = 0;
00098     }
00099 }
00100 
00101 int main() {
00102     // TODO replace your filename
00103     fp = fopen("/mbed/tas.txt", "rb");
00104     controllerDataPosition = 0;
00105 
00106     fseek(fp, 0L, SEEK_END);
00107     fileLength = ftell(fp);
00108     fseek(fp, 0L, SEEK_SET);
00109 
00110     fread(controllerData, 1, BUFFER_LENGTH, fp);
00111     writeButtons();    
00112     
00113     latchInterrupt.mode(PullNone);
00114     latchInterrupt.fall(&trigger);
00115     
00116     while(!finished);
00117     fclose(fp);
00118 }