An Arduous Endeavor (Part 4): Input Handling

This entry is part 4 of 7 in the series An Arduous Endeavor

Playing games usually requires pressing buttons. I thought this part would take longer, but it turned out to be almost too simple.

Arduinos typically get external input via various pins. While there is technically some sort of setup/configuration necessary to be able to read data from these, when programs actually access them, they just read from an address in the “RAM” of the AVR.

Turns out that, since I’m emulating the CPU, I can just put whatever I want in that address.

#define PINB 0x23
#define PINE 0x2c
#define PINF 0x2f

void Arduous::setButtonState(ArduousButtonState newButtonState) {
    cpu->data[PINB] = (!newButtonState.buttonB << 4) | (cpu->data[PINB] & 0xEF);
    cpu->data[PINE] = (!newButtonState.buttonA << 6) | (cpu->data[PINE] & 0xBF);
    cpu->data[PINF] = (!newButtonState.buttonUp << 7) | (!newButtonState.buttonRight << 6) |
                      (!newButtonState.buttonLeft << 5) | (!newButtonState.buttonDown << 4) | (cpu->data[PINF] & 0x0F);

This isn’t particularly elegant, but it gets the job done. I may look into doing something with callbacks or somehow ensuring that I’m only writing to that spot in RAM if the port is set up for digital input, but for now, this gets me input, and I can actually play games in my emulator!

Series Navigation<< An Arduous Endeavor (Part 3): CPU EmulationAn Arduous Endeavor (Part 5): Buzzes and Beeps >>

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.