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

main.cpp

Committer:
kshoji
Date:
2012-01-07
Revision:
0:19e971e75a74

File content as of revision 0:19e971e75a74:

#include "mbed.h"

// - The porting of the NESBot
// original : http://www.instructables.com/id/NESBot-Arduino-Powered-Robot-beating-Super-Mario-/
// 
// ported by Kaoru Shoji : http://mbed.org/users/kshoji
// 
// - Connections:
// a NES, a mbed and a 4021 (shift register) needed.
// 
// for example) AV-FAMICOM(JPY) connector pinout
// 1 LATCH (PL, P/S)    -> mbed's 9 pin
// 2 CLOCK              -> 4021's 10 pin
// 3 VCC                -> 4021's 16 pin
// 4 GND                -> mbed's GND & 4021's 8 pin
// 5 DATA               -> 4021's 3 pin
// 
// - Note:
// The mbed's VCC must be supplied from USB cable.
// If mbed's VCC is supplied from NES VCC, the LATCH signal detection may be failed.
// 
// - How to use:
// 0. Prepare the replay data with FCEUX and Lua script. (Lua script can be downloaded from instructables).
//    The data file needs to be placed into mbed's LocalFileSystem(on the root directory).
// 1. NES power turn off.
// 2. connect mbed to NES, and USB power.
// 3. NES power turn on.

InterruptIn latchInterrupt(p9); // LATCH signal in

DigitalOut R(p10); // -> 4021's p1(7)
DigitalOut L(p11); // -> 4021's p2(6)
DigitalOut D(p12); // -> 4021's p3(5)
DigitalOut U(p13); // -> 4021's p4(4)
DigitalOut T(p14); // -> 4021's p5(13)
DigitalOut S(p15); // -> 4021's p6(14)
DigitalOut B(p16); // -> 4021's p7(15)
DigitalOut A(p17); // -> 4021's p8(1)

// status LEDs
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

LocalFileSystem local("mbed");

// Large buffer may cause time rag when file loading.
#define BUFFER_LENGTH (128)

unsigned char controllerData[BUFFER_LENGTH];
int controllerDataPosition = 0;

FILE *fp;
long fileLength = 0;
long filePosition = 0;

volatile bool finished = false;

void writeButtons() {
    unsigned char state = ~controllerData[controllerDataPosition];

    // output to shift register
    R = state & 0x80;
    L = state & 0x40;
    D = state & 0x20;
    U = state & 0x10;
    T = state & 0x08;
    S = state & 0x04;
    B = state & 0x02;
    A = state & 0x01;
}

void showLEDs() {
    led1 = !U | !D;
    led2 = !L | !R;
    led3 = !A;
    led4 = !B;
}

void trigger() {
    // when P/S Control signal falled(Serial mode)
    // read the controller state
    writeButtons();
    showLEDs();

    filePosition++;
    if (filePosition >= fileLength) {
        latchInterrupt.fall(0);
        finished = true;
        return;
    }

    controllerDataPosition++;
    if (controllerDataPosition >= BUFFER_LENGTH) {
        fread(controllerData, 1, BUFFER_LENGTH, fp);
        controllerDataPosition = 0;
    }
}

int main() {
    // TODO replace your filename
    fp = fopen("/mbed/tas.txt", "rb");
    controllerDataPosition = 0;

    fseek(fp, 0L, SEEK_END);
    fileLength = ftell(fp);
    fseek(fp, 0L, SEEK_SET);

    fread(controllerData, 1, BUFFER_LENGTH, fp);
    writeButtons();    
    
    latchInterrupt.mode(PullNone);
    latchInterrupt.fall(&trigger);
    
    while(!finished);
    fclose(fp);
}