Could be a lot better than it is now. I think having a struct hold all the state is the right step forward, but perhaps putting that in its own single header, separating all the I/O processing functions away from that would help.
If things only need to include chip8.h for just A FEW things, then we can modify some functions to pass that as a parameter instead of including the entire header..