package nes // bit order matches the order the console reads them out in const ( ButtonA uint8 = 1 << iota ButtonB ButtonSelect ButtonStart ButtonUp ButtonDown ButtonLeft ButtonRight ) // standard controller, it is just an 8 bit shift register // https://www.nesdev.org/wiki/Standard_controller type controller struct { buttons uint8 // what is held right now shift uint8 // what the cpu is reading out strobe bool } // while strobe is high the shift register keeps copying the buttons func (c *controller) setStrobe(on bool) { c.strobe = on if on { c.shift = c.buttons } } func (c *controller) setButtons(b uint8) { c.buttons = b if c.strobe { c.shift = b } } // returns one button per read, A first. with strobe high it stays on A func (c *controller) read() uint8 { bit := c.shift & 1 if !c.strobe { // ones get shifted in, so reads after the 8th return 1 c.shift = c.shift>>1 | 0x80 } // upper bits are open bus, which is $40 here since that is the high byte // of the address that was read return 0x40 | bit } // port is 0 for controller 1 and 1 for controller 2 func (n *Console) SetButtons(port int, buttons uint8) { n.controllers[port].setButtons(buttons) }