Nintendo 64 controller is read by NicoHood's Nintendo library and the buttons are converted to MSX equivalents according to the table below.
Analog stick is mapped to MSX controllers using a paddle emulation function that responds to an interrupt that is generated by a rising edge on pin 8 (pulse) of joystick port.
The tricky part of this project is that Nintendo64 reading library has a time critical portion that takes about 157us with interrupts disabled, then if a paddle reading pulse arrives while the AVR is sampling the N64 controller, the interrupt service routine will be neld by up to 157us, which correscorresponds to 8 out of 255 counting loops performed by MSX to read the paddles. Too much time!
The solution is based on a premise that whenever a program will read the paddles to do something useful, it will do it periodically, usually at the video vertical sync frequency (50/60Hz depending on the MSX origin country ).
Here is how the code is wrapped:
- The main loop will sample the N64 controller and update the AVR outputs accordingly. Then the cpu will sleep.
- A second interrupt will be used, attached to Timer 1 which is set to interrupt at a interval of 10ms. This interrupt solely wakes up the processor and set the interrupt AGAIN for a 10ms interval
Whenever an external interrupt occur, it will:
- reinitialize the Timer 1
- set a NEW period of Timer overflow to 100ms
- Do the paddle emulation
Summarizing, the Timer 1 wakes up the AVR after a variable timeout. When no paddle reading pulses are coming the timeout is 10ms.
First paddle reading pulse set a new (100ms) timeout interval, which is longer than the usual 16.67/20ms expected for a game loop (even in a BASIC program).
Consecutive paddle reading pulses (within 100ms) reinitialize the timer so no timeout occurs while paddle is being continously reading.
100ms after the paddle reading pulses cease, the timeout will occur to wake up the CPU and the timeout period will be restablished as 10ms.