-
Notifications
You must be signed in to change notification settings - Fork 0
/
borzgbc_test.go
300 lines (237 loc) · 6.48 KB
/
borzgbc_test.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
package main
import (
"fmt"
"image"
"image/color"
"image/png"
"os"
"strings"
"testing"
"borzGBC/pkg/gbc"
)
/*
* Test Frontend
*/
type ImageVideoDriver struct {
backImg *image.RGBA
frontImg *image.RGBA
num int
SerialFunction func(sb, sc uint8) (uint8, uint8)
}
func MkImageVideoDriver() *ImageVideoDriver {
res := &ImageVideoDriver{}
upLeft := image.Point{0, 0}
lowRight := image.Point{160, 144}
res.backImg = image.NewRGBA(image.Rectangle{upLeft, lowRight})
res.frontImg = image.NewRGBA(image.Rectangle{upLeft, lowRight})
return res
}
func (d *ImageVideoDriver) SetPixel(x, y int, c uint32) {
var r, g, b, a uint8
r = uint8((c >> 24) & 0xFF)
g = uint8((c >> 16) & 0xFF)
b = uint8((c >> 8) & 0xFF)
a = uint8(c & 0xFF)
d.backImg.SetRGBA(x, y, color.RGBA{r, g, b, a})
}
func (d *ImageVideoDriver) CommitScreen() {
d.frontImg = d.backImg
d.num += 1
}
func (d *ImageVideoDriver) SaveScreen(path string) {
f, _ := os.Create(path)
defer f.Close()
png.Encode(f, d.frontImg)
}
func (pl *ImageVideoDriver) NotifyAudioSample(l, r int8) {
// Ignore audio
}
func (pl *ImageVideoDriver) GetCurrentImage() *image.RGBA {
return pl.frontImg
}
func (pl *ImageVideoDriver) ExchangeSerial(sb, sc uint8) (uint8, uint8) {
if pl.SerialFunction != nil {
return pl.SerialFunction(sb, sc)
}
return 0, 0
}
func imagesAreEqual(img1, img2 image.Image) bool {
if img1.Bounds() != img2.Bounds() {
return false
}
for x := img1.Bounds().Min.X; x < img1.Bounds().Max.X; x++ {
for y := img1.Bounds().Min.Y; y < img1.Bounds().Max.Y; y++ {
if img1.At(x, y) != img2.At(x, y) {
return false
}
}
}
return true
}
/*
* Utility functions
*/
func runRomTestWithSerial(t *testing.T, test string, frames int, serialFunction func(sb, sc uint8) (uint8, uint8)) {
testName := strings.Split(test, ".")[0]
pl := MkImageVideoDriver()
pl.SerialFunction = serialFunction
romPath := fmt.Sprintf("test/data/%s", test)
rom, err := os.ReadFile(romPath)
if err != nil {
t.Error(err)
return
}
console, err := gbc.MakeConsole(rom, pl)
if err != nil {
t.Error("Unable to create console")
return
}
console.PPU.GBPalette = gbc.GB_PALETTE_GREY
for console.PPU.FrameCount < frames {
console.Step()
}
pl.SaveScreen(fmt.Sprintf("test/data/%s.result.png", testName))
f, err := os.Open(fmt.Sprintf("test/data/%s.png", testName))
if err != nil {
t.Error("Unable to read expected screen")
return
}
defer f.Close()
expected, err := png.Decode(f)
if err != nil {
t.Error("Unable to decode expected screen")
return
}
if !imagesAreEqual(expected, pl.GetCurrentImage()) {
t.Fail()
}
}
/*
* Real tests
*/
func runRomTest(t *testing.T, test string, frames int) {
runRomTestWithSerial(t, test, frames, nil)
}
func TestBlargCpuInstrs(t *testing.T) {
runRomTest(t, "Blargg/cpu_instrs.gb", 4000)
}
func TestBlargInstrTiming(t *testing.T) {
runRomTest(t, "Blargg/instr_timing.gb", 1000)
}
func TestDMGAcid2(t *testing.T) {
runRomTest(t, "MattCurrie/dmg-acid2.gb", 1000)
}
func TestCGBAcid2(t *testing.T) {
runRomTest(t, "MattCurrie/cgb-acid2.gbc", 1000)
}
func TestMooneyeOamDma_basic(t *testing.T) {
runRomTest(t, "Mooneye/oam_dma/basic.gb", 1000)
}
func TestMooneyeOamDma_reg_read(t *testing.T) {
runRomTest(t, "Mooneye/oam_dma/reg_read.gb", 1000)
}
func TestMooneyeBits_mem_oam(t *testing.T) {
runRomTest(t, "Mooneye/bits/mem_oam.gb", 1000)
}
func TestMooneyeBits_reg_f(t *testing.T) {
runRomTest(t, "Mooneye/bits/reg_f.gb", 1000)
}
func TestMooneye_sprite_priority(t *testing.T) {
runRomTest(t, "Mooneye/sprite_priority.gb", 1000)
}
func TestMooneyeTimer_div_write(t *testing.T) {
runRomTest(t, "Mooneye/timer/div_write.gb", 1000)
}
func TestMooneyeTimer_tim00(t *testing.T) {
runRomTest(t, "Mooneye/timer/tim00.gb", 1000)
}
func TestMooneyeTimer_tim10(t *testing.T) {
runRomTest(t, "Mooneye/timer/tim10.gb", 1000)
}
func TestMooneyeTimer_tim11(t *testing.T) {
runRomTest(t, "Mooneye/timer/tim11.gb", 1000)
}
func TestMooneyeMbc1_bits_bank1(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/bits_bank1.gb", 1000)
}
func TestMooneyeMbc1_bits_bank2(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/bits_bank2.gb", 1000)
}
func TestMooneyeMbc1_bits_mode(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/bits_mode.gb", 1000)
}
func TestMooneyeMbc1_bits_ramg(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/bits_ramg.gb", 1000)
}
func TestMooneyeMbc1_ram_64kb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/ram_64kb.gb", 1000)
}
func TestMooneyeMbc1_ram_256kb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/ram_256kb.gb", 1000)
}
func TestMooneyeMbc1_rom_1Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/rom_1Mb.gb", 1000)
}
func TestMooneyeMbc1_rom_2Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/rom_2Mb.gb", 1000)
}
func TestMooneyeMbc1_rom_4Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/rom_4Mb.gb", 1000)
}
func TestMooneyeMbc1_rom_8Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/rom_8Mb.gb", 1000)
}
func TestMooneyeMbc1_rom_16Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/rom_16Mb.gb", 1000)
}
func TestMooneyeMbc1_rom_512Kb(t *testing.T) {
runRomTest(t, "Mooneye/mbc1/rom_512kb.gb", 1000)
}
func TestMooneyeMbc5_rom_1Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_1Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_2Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_2Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_4Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_4Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_8Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_8Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_16Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_16Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_32Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_32Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_64Mb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_64Mb.gb", 1000)
}
func TestMooneyeMbc5_rom_512Kb(t *testing.T) {
runRomTest(t, "Mooneye/mbc5/rom_512kb.gb", 1000)
}
func TestMooneyeIntr_1_2(t *testing.T) {
runRomTest(t, "Mooneye/interrupts/intr_1_2_timing-GS.gb", 1000)
}
func TestMooneyeIntr_2_0(t *testing.T) {
runRomTest(t, "Mooneye/interrupts/intr_2_0_timing.gb", 1000)
}
func TestMooneyeIntrStatIrq(t *testing.T) {
// This fails, but it proceeds further with respect to the previous version
runRomTest(t, "Mooneye/interrupts/stat_irq_blocking.gb", 1000)
}
func TestSerial(t *testing.T) {
fistRun := true
runRomTestWithSerial(t, "Serial/gb-link.gb", 1000, func(sb, sc uint8) (uint8, uint8) {
if sc == 0x80 {
if fistRun {
fistRun = false
return 2, 0x81
} else {
return 0xaa, 0x81
}
}
return 0, 0
})
}