/
cpu.go
135 lines (112 loc) · 2.68 KB
/
cpu.go
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package gb
import (
"github.com/Humpheh/goboy/pkg/bits"
)
// Register represents a GB CPU 16bit register which provides functions
// for setting and getting the higher and lower bytes.
type register struct {
// The value of the register.
Val uint16
// A mask over the possible values in the register.
// Only used for the AF register where lower bits of
// F cannot be set.
Mask uint16
}
// Hi gets the higher byte of the register.
func (reg *register) Hi() byte {
return byte(reg.Val >> 8)
}
// Lo gets the lower byte of the register.
func (reg *register) Lo() byte {
return byte(reg.Val & 0xFF)
}
// HiLo gets the 2 byte value of the register.
func (reg *register) HiLo() uint16 {
return reg.Val
}
// SetHi sets the higher byte of the register.
func (reg *register) SetHi(val byte) {
reg.Val = uint16(val)<<8 | (uint16(reg.Val) & 0xFF)
reg.updateMask()
}
// SetLog sets the lower byte of the register.
func (reg *register) SetLo(val byte) {
reg.Val = uint16(val) | (uint16(reg.Val) & 0xFF00)
reg.updateMask()
}
// Set the value of the register.
func (reg *register) Set(val uint16) {
reg.Val = val
reg.updateMask()
}
// Mask the value if one is set on this register.
func (reg *register) updateMask() {
if reg.Mask != 0 {
reg.Val &= reg.Mask
}
}
// CPU contains the registers used for program execution and
// provides methods for setting flags.
type CPU struct {
AF register
BC register
DE register
HL register
PC uint16
SP register
Divider int
}
// Init CPU and its registers to the initial values.
func (cpu *CPU) Init(cgb bool) {
cpu.PC = 0x100
if cgb {
cpu.AF.Set(0x1180)
} else {
cpu.AF.Set(0x01B0)
}
cpu.BC.Set(0x0000)
cpu.DE.Set(0xFF56)
cpu.HL.Set(0x000D)
cpu.SP.Set(0xFFFE)
cpu.AF.Mask = 0xFFF0
}
// Internally set the value of a flag on the flag register.
func (cpu *CPU) setFlag(index byte, on bool) {
if on {
cpu.AF.SetLo(bits.Set(cpu.AF.Lo(), index))
} else {
cpu.AF.SetLo(bits.Reset(cpu.AF.Lo(), index))
}
}
// SetZ sets the value of the Z flag.
func (cpu *CPU) SetZ(on bool) {
cpu.setFlag(7, on)
}
// SetN sets the value of the N flag.
func (cpu *CPU) SetN(on bool) {
cpu.setFlag(6, on)
}
// SetH sets the value of the H flag.
func (cpu *CPU) SetH(on bool) {
cpu.setFlag(5, on)
}
// SetC sets the value of the C flag.
func (cpu *CPU) SetC(on bool) {
cpu.setFlag(4, on)
}
// Z gets the value of the Z flag.
func (cpu *CPU) Z() bool {
return cpu.AF.HiLo()>>7&1 == 1
}
// N gets the value of the N flag.
func (cpu *CPU) N() bool {
return cpu.AF.HiLo()>>6&1 == 1
}
// H gets the value of the H flag.
func (cpu *CPU) H() bool {
return cpu.AF.HiLo()>>5&1 == 1
}
// C gets the value of the C flag.
func (cpu *CPU) C() bool {
return cpu.AF.HiLo()>>4&1 == 1
}