Quick Start
Let’s create your first Dreamcast Go program.
Create a Project
mkdir myproject && cd myproject
godc init
Example output:
$ godc init
go: found kos in kos v0.0.0-00010101000000-000000000000
This creates go.mod and go.work files that configure your project to use the kos package from your libgodc installation.
Project Structure
A minimal project looks like this:
myproject/
├── go.mod # Module definition with kos dependency
├── go.work # Workspace configuration
└── main.go # Your code
The go.mod file (paths will match your libgodc location):
module myproject
go 1.25.3
replace kos => /path/to/your/libgodc/kos
require kos v0.0.0-00010101000000-000000000000
The go.work file:
go 1.25.3
use (
/path/to/your/libgodc
.
)
Note: The paths in
go.modandgo.workwill automatically point to your libgodc installation location.
Hello, Dreamcast!
Create main.go:
package main
import "kos"
func main() {
kos.PvrInitDefaults()
println("Hello, Dreamcast!")
for {}
}
Build and Run
Using godc:
godc build # Compile to .elf
godc run # Launch in emulator
Or manually with sh-elf-gccgo:
sh-elf-gccgo -O2 -ml -m4-single -fno-split-stack -mfsrra -mfsca \
-I$KOS_BASE/lib -L$KOS_BASE/lib \
-c main.go -o main.o
kos-cc -o myproject.elf main.o \
-L$KOS_BASE/lib -Wl,--whole-archive -lgodcbegin \
-Wl,--no-whole-archive -lkos -lgodc
Your First Graphics
Let’s draw something on screen:
package main
import "kos"
func main() {
kos.PvrInitDefaults()
for {
kos.PvrWaitReady()
kos.PvrSceneBegin()
// Draw opaque geometry
kos.PvrListBegin(kos.PVR_LIST_OP_POLY)
drawTriangle()
kos.PvrListFinish()
kos.PvrSceneFinish()
}
}
func drawTriangle() {
// Create and submit polygon header
var hdr kos.PvrPolyHdr
var ctx kos.PvrPolyCxt
kos.PvrPolyCxtCol(&ctx, kos.PVR_LIST_OP_POLY)
kos.PvrPolyCompile(&hdr, &ctx)
kos.PvrPrim(&hdr) // Submit header
// Submit vertices (use PvrPrimVertex for vertices)
v := kos.PvrVertex{
Flags: kos.PVR_CMD_VERTEX,
X: 320, Y: 100, Z: 1,
ARGB: 0xFFFF0000, // Red
}
kos.PvrPrimVertex(&v)
v.X, v.Y = 200, 400
v.ARGB = 0xFF00FF00 // Green
kos.PvrPrimVertex(&v)
v.X, v.Y = 440, 400
v.Flags = kos.PVR_CMD_VERTEX_EOL // End of strip
v.ARGB = 0xFF0000FF // Blue
kos.PvrPrimVertex(&v)
}
Using Goroutines
Goroutines work on Dreamcast:
package main
import "kos"
func main() {
kos.PvrInitDefaults()
// Start a background goroutine
go func() {
counter := 0
for {
counter++
println("Background:", counter)
select {} // Yield to scheduler
}
}()
// Main loop
for {
kos.PvrWaitReady()
kos.PvrSceneBegin()
render()
kos.PvrSceneFinish()
}
}
Using Channels
Channels enable communication between goroutines:
package main
import "kos"
func main() {
kos.PvrInitDefaults()
// Create a buffered channel
scores := make(chan int, 10)
// Score counter goroutine
go func() {
total := 0
for score := range scores {
total += score
println("Total score:", total)
}
}()
// Main game loop
for {
// Game logic
if playerScored() {
scores <- 100 // Send score
}
render()
}
}
Next Steps
- Read the Design Document to understand the runtime architecture
- Check out the examples/ directory for working programs
- Read Effective Dreamcast Go for best practices