Skip to content

Commit 125dac4

Browse files
committed
Hello boy 🎉
0 parents  commit 125dac4

File tree

253 files changed

+10252
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

253 files changed

+10252
-0
lines changed

.circleci/config.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
defaults: &defaults
2+
working_directory: ~/gopher-boy
3+
docker:
4+
- image: bokuweb/node-go-with-browser:latest
5+
environment:
6+
TZ: Asia/Tokyo
7+
GOPATH: /home/circleci/go
8+
version: 2
9+
jobs:
10+
build:
11+
<<: *defaults
12+
steps:
13+
- checkout
14+
- run:
15+
name: Install dependencies
16+
command: apt-get install -yq xorg-dev libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libopenal-dev libasound2-dev libgl1-mesa-dev
17+
- run:
18+
name: Install reg
19+
command: npm i -g reg-cli
20+
- run:
21+
name: Test
22+
command: |
23+
make -B test
24+
- run:
25+
name: Reg
26+
command: reg-cli ./test/actual ./test/expect ./test/diff

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
reg.json
2+
logs/*.log
3+
*.sym
4+
logs

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Launch",
9+
"type": "go",
10+
"request": "launch",
11+
"mode": "auto",
12+
"program": "${workspaceRoot}/cmd/gopher-boy/main.go",
13+
"env": {
14+
"GO111MODULE": "on",
15+
"LEVEL": "info"
16+
},
17+
"args": ["${workspaceRoot}/roms/cpu_instrs/02-interrupts.gb"]
18+
}
19+
]
20+
}

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# gopher-boy
2+
3+
[![CircleCI](https://circleci.com/gh/bokuweb/gopher-boy.svg?style=svg&circle-token=3592e6b575eb46c09b22f0497b6e595f9f16f372)](https://circleci.com/gh/bokuweb/gopher-boy)
4+

cmd/go-boy/main.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"log"
6+
"os"
7+
8+
"github.com/bokuweb/gopher-boy/pkg/interrupt"
9+
"github.com/bokuweb/gopher-boy/pkg/pad"
10+
11+
"github.com/bokuweb/gopher-boy/pkg/gpu"
12+
"github.com/bokuweb/gopher-boy/pkg/timer"
13+
"github.com/bokuweb/gopher-boy/pkg/utils"
14+
15+
"github.com/bokuweb/gopher-boy/pkg/cpu"
16+
"github.com/bokuweb/gopher-boy/pkg/gb"
17+
"github.com/bokuweb/gopher-boy/pkg/logger"
18+
"github.com/bokuweb/gopher-boy/pkg/ram"
19+
20+
"github.com/bokuweb/gopher-boy/pkg/bus"
21+
"github.com/bokuweb/gopher-boy/pkg/cartridge"
22+
"github.com/bokuweb/gopher-boy/pkg/window"
23+
)
24+
25+
func main() {
26+
level := "Debug"
27+
if os.Getenv("LEVEL") != "" {
28+
level = os.Getenv("LEVEL")
29+
}
30+
l := logger.NewLogger(logger.LogLevel(level))
31+
if len(os.Args) != 2 {
32+
log.Fatalf("ERROR: %v", errors.New("Please specify the ROM"))
33+
}
34+
file := os.Args[1]
35+
log.Println(file)
36+
buf, err := utils.LoadROM(file)
37+
if err != nil {
38+
log.Fatalf("ERROR: %v", errors.New("Failed to load ROM"))
39+
}
40+
cart, err := cartridge.NewCartridge(buf)
41+
if err != nil {
42+
log.Fatalf("ERROR: %v", errors.New("Failed to create cartridge"))
43+
}
44+
vRAM := ram.NewRAM(0x2000)
45+
wRAM := ram.NewRAM(0x2000)
46+
hRAM := ram.NewRAM(0x80)
47+
oamRAM := ram.NewRAM(0xA0)
48+
gpu := gpu.NewGPU()
49+
t := timer.NewTimer()
50+
pad := pad.NewPad()
51+
irq := interrupt.NewInterrupt()
52+
b := bus.NewBus(l, cart, gpu, vRAM, wRAM, hRAM, oamRAM, t, irq, pad)
53+
gpu.Init(b, irq)
54+
win := window.NewWindow(pad)
55+
emu := gb.NewGB(cpu.NewCPU(l, b, irq), gpu, t, irq, win)
56+
win.Run(func() {
57+
win.Init()
58+
emu.Start()
59+
})
60+
}

go.mod

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module github.com/bokuweb/gopher-boy
2+
3+
require (
4+
github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380 // indirect
5+
github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 // indirect
6+
github.com/faiface/pixel v0.8.0
7+
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 // indirect
8+
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 // indirect
9+
github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7 // indirect
10+
github.com/pkg/errors v0.8.1 // indirect
11+
github.com/stretchr/testify v1.3.0
12+
golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff
13+
)

go.sum

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380 h1:FvZ0mIGh6b3kOITxUnxS3tLZMh7yEoHo75v3/AgUqg0=
4+
github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380/go.mod h1:zqnPFFIuYFFxl7uH2gYByJwIVKG7fRqlqQCbzAnHs9g=
5+
github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q=
6+
github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M=
7+
github.com/faiface/pixel v0.8.0 h1:phOHW6ixfMAKRamjnvhI6FFI2VRyPEq7+LmmkDGXB/4=
8+
github.com/faiface/pixel v0.8.0/go.mod h1:CEUU/s9E82Kqp01Boj1O67KnBskqiLghANqvUJGgDAM=
9+
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw=
10+
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
11+
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
12+
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
13+
github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7 h1:THttjeRn1iiz69E875U6gAik8KTWk/JYAHoSVpUxBBI=
14+
github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
15+
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
16+
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
17+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
18+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
19+
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
20+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
21+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
22+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
23+
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f h1:FO4MZ3N56GnxbqxGKqh+YTzUWQ2sDwtFQEZgLOxh9Jc=
24+
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
25+
golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff h1:+2zgJKVDVAz/BWSsuniCmU1kLCjL88Z8/kv39xCI9NQ=
26+
golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
27+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
test:
2+
GO111MODULE=on go test github.com/bokuweb/gopher-boy/...
3+
4+
reg:
5+
reg-cli ./test/actual ./test/expect ./test/diff
6+
7+
reg-update:
8+
reg-cli ./test/actual ./test/expect ./test/diff -U

pkg/bus/bus.go

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package bus
2+
3+
import (
4+
"github.com/bokuweb/gopher-boy/pkg/interfaces/pad"
5+
"github.com/bokuweb/gopher-boy/pkg/interrupt"
6+
7+
"github.com/bokuweb/gopher-boy/pkg/cartridge"
8+
"github.com/bokuweb/gopher-boy/pkg/gpu"
9+
"github.com/bokuweb/gopher-boy/pkg/interfaces/logger"
10+
"github.com/bokuweb/gopher-boy/pkg/ram"
11+
"github.com/bokuweb/gopher-boy/pkg/serial"
12+
"github.com/bokuweb/gopher-boy/pkg/timer"
13+
"github.com/bokuweb/gopher-boy/pkg/types"
14+
"github.com/bokuweb/gopher-boy/pkg/utils"
15+
)
16+
17+
const (
18+
// DMGStatusReg is DMA status register
19+
DMGStatusReg types.Word = 0xFF50
20+
)
21+
22+
// Bus is gb bus
23+
type Bus struct {
24+
logger logger.Logger
25+
bootmode bool
26+
cartridge *cartridge.Cartridge
27+
gpu *gpu.GPU
28+
vRAM *ram.RAM
29+
wRAM *ram.RAM
30+
hRAM *ram.RAM
31+
oamRAM *ram.RAM
32+
timer *timer.Timer
33+
irq *interrupt.Interrupt
34+
pad pad.Pad
35+
}
36+
37+
/* --------------------------+
38+
| Interrupt Enable Register |
39+
------------------------------ 0xFFFF
40+
| Internal RAM |
41+
------------------------------ 0xFF80
42+
| Empty but unusable for I/O |
43+
------------------------------ 0xFF4C
44+
| I/O ports |
45+
------------------------------ 0xFF00
46+
| Empty but unusable for I/O |
47+
------------------------------ 0xFEA0
48+
| Sprite Attrib Memory (OAM) |
49+
------------------------------ 0xFE00
50+
| Echo of 8kB Internal RAM |
51+
------------------------------ 0xE000
52+
| 8kB Internal RAM |
53+
------------------------------ 0xC000
54+
| 8kB switchable RAM bank |
55+
------------------------------ 0xA000
56+
| 8kB Video RAM |
57+
------------------------------ 0x8000 --+
58+
| 16kB switchable ROM bank | |
59+
------------------------------ 0x4000 | = 32kB Cartrigbe
60+
| 16kB ROM bank #0 | |
61+
------------------------------ 0x0000 --+ */
62+
63+
// NewBus is bus constructor
64+
func NewBus(
65+
logger logger.Logger,
66+
cartridge *cartridge.Cartridge,
67+
gpu *gpu.GPU,
68+
vram *ram.RAM,
69+
wram *ram.RAM,
70+
hRAM *ram.RAM,
71+
oamRAM *ram.RAM,
72+
timer *timer.Timer,
73+
irq *interrupt.Interrupt,
74+
pad pad.Pad) *Bus {
75+
return &Bus{
76+
logger: logger,
77+
bootmode: true,
78+
cartridge: cartridge,
79+
gpu: gpu,
80+
vRAM: vram,
81+
wRAM: wram,
82+
hRAM: hRAM,
83+
oamRAM: oamRAM,
84+
timer: timer,
85+
irq: irq,
86+
pad: pad,
87+
}
88+
}
89+
90+
// ReadByte is byte data reader from bus
91+
func (b *Bus) ReadByte(addr types.Word) byte {
92+
switch {
93+
case addr >= 0x0000 && addr <= 0x7FFF:
94+
if b.bootmode && addr < 0x0100 {
95+
return BIOS[addr]
96+
}
97+
if addr == 0x0100 {
98+
b.bootmode = false
99+
}
100+
return b.cartridge.ReadByte(addr)
101+
// Video RAM
102+
case addr >= 0x8000 && addr <= 0x9FFF:
103+
return b.vRAM.Read(addr - 0x8000)
104+
case addr >= 0xA000 && addr <= 0xBFFF:
105+
return b.cartridge.ReadByte(addr)
106+
// Working RAM
107+
case addr >= 0xC000 && addr <= 0xDFFF:
108+
return b.wRAM.Read(addr - 0xC000)
109+
// Shadow
110+
case addr >= 0xE000 && addr <= 0xFDFF:
111+
return b.wRAM.Read(addr - 0xE000)
112+
// OAM
113+
case addr >= 0xFE00 && addr <= 0xFE9F:
114+
return b.oamRAM.Read(addr - 0xFE00)
115+
// Pad
116+
case addr == 0xFF00:
117+
return b.pad.Read()
118+
// Timer
119+
case addr >= 0xFF04 && addr <= 0xFF07:
120+
return b.timer.Read(addr - 0xFF00)
121+
// IF
122+
case addr == 0xFF0F:
123+
return b.irq.Read(addr - 0xFF00)
124+
// GPU
125+
case addr >= 0xFF40 && addr <= 0xFF7F:
126+
return b.gpu.Read(addr - 0xFF40)
127+
// Zero page RAM
128+
case addr >= 0xFF80 && addr <= 0xFFFE:
129+
return b.hRAM.Read(addr - 0xFF80)
130+
// IE
131+
case addr == 0xFFFF:
132+
return b.irq.Read(addr - 0xFF00)
133+
default:
134+
return 0
135+
}
136+
return 0
137+
}
138+
139+
// ReadWord is word data reader from bus
140+
func (b *Bus) ReadWord(addr types.Word) types.Word {
141+
l := b.ReadByte(addr)
142+
u := b.ReadByte(addr + 1)
143+
return utils.Bytes2Word(u, l)
144+
}
145+
146+
// WriteByte is byte data writer to bus
147+
func (b *Bus) WriteByte(addr types.Word, data byte) {
148+
switch {
149+
case addr >= 0x0000 && addr <= 0x7FFF:
150+
b.cartridge.WriteByte(addr, data)
151+
// Video RAM
152+
case addr >= 0x8000 && addr <= 0x9FFF:
153+
b.vRAM.Write(addr-0x8000, data)
154+
case addr >= 0xA000 && addr <= 0xBFFF:
155+
b.cartridge.WriteByte(addr, data)
156+
// Working RAM
157+
case addr >= 0xC000 && addr <= 0xDFFF:
158+
b.wRAM.Write(addr-0xC000, data)
159+
// Shadow
160+
case addr >= 0xE000 && addr <= 0xFDFF:
161+
b.wRAM.Write(addr-0xE000, data)
162+
// OAM
163+
case addr >= 0xFE00 && addr <= 0xFE9F:
164+
b.oamRAM.Write(addr-0xFE00, data)
165+
// Pad
166+
case addr == 0xFF00:
167+
b.pad.Write(data)
168+
// Serial
169+
case addr == 0xFF01:
170+
serial.Send(data)
171+
// Timer
172+
case addr >= 0xFF04 && addr <= 0xFF07:
173+
b.timer.Write(addr-0xFF00, data)
174+
// IF
175+
case addr == 0xFF0F:
176+
b.irq.Write(addr-0xFF00, data)
177+
// GPU
178+
case addr >= 0xFF40 && addr <= 0xFF7F:
179+
b.gpu.Write(addr-0xFF40, data)
180+
//Zero page RAM
181+
case addr >= 0xFF80 && addr <= 0xFFFE:
182+
b.hRAM.Write(addr-0xFF80, data)
183+
// IE
184+
case addr == 0xFFFF:
185+
b.irq.Write(addr-0xFF00, data)
186+
default:
187+
// fmt.Printf("Error: You can not write 0x%X, this area is invalid or unimplemented area.\n", addr)
188+
}
189+
}
190+
191+
// WriteWord is word data writer to bus
192+
func (b *Bus) WriteWord(addr types.Word, data types.Word) {
193+
upper, lower := utils.Word2Bytes(data)
194+
b.WriteByte(addr, lower)
195+
b.WriteByte(addr+1, upper)
196+
}
197+
198+
// BIOS is
199+
var BIOS = []byte{ /* Removed*/ }

0 commit comments

Comments
 (0)