aboutsummaryrefslogtreecommitdiff
path: root/nes/controller.go
blob: 51afe20d7d0652e9cd967d4acab0c93dc308b700 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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)
}