gb-player/gb/bus.go

93 lines
2.0 KiB
Go

package gb
import (
"fmt"
)
// 0x0000 - 0x3FFF : ROM Bank 0
// 0x4000 - 0x7FFF : ROM Bank 1 - Switchable
// 0x8000 - 0x97FF : CHR RAM
// 0x9800 - 0x9BFF : BG Map 1
// 0x9C00 - 0x9FFF : BG Map 2
// 0xA000 - 0xBFFF : Cartridge RAM
// 0xC000 - 0xCFFF : RAM Bank 0
// 0xD000 - 0xDFFF : RAM Bank 1-7 - switchable - Color only
// 0xE000 - 0xFDFF : Reserved - Echo RAM
// 0xFE00 - 0xFE9F : Object Attribute Memory
// 0xFEA0 - 0xFEFF : Reserved - Unusable
// 0xFF00 - 0xFF7F : I/O Registers
// 0xFF80 - 0xFFFE : Zero Page
type Bus struct {
Cart *Cartridge
RAM *RAM
}
func NewBus(cart *Cartridge) *Bus {
bus := Bus{Cart: cart, RAM: NewRAM()}
return &bus
}
func (bus *Bus) Read(address uint16) byte {
if address < 0x8000 {
// ROM data
value, err := bus.Cart.Read(address)
if err != nil {
fmt.Printf("Error reading from bus address %X: %s", address, err)
return 0
}
return value
} else if address < 0xE000 {
//WRAM (Working RAM)
return bus.RAM.WRAMRead(address)
} else if address < 0xFF80 {
//IO Registers
return IORead(address)
} else {
fmt.Printf("Reading from bus address %X not implemented!\n", address)
return 0
}
}
func (bus *Bus) Read16(address uint16) uint16 {
lo := bus.Read(address)
hi := bus.Read(address + 1)
return uint16(lo) | uint16(hi)<<8
}
func (bus *Bus) Write(address uint16, value byte) error {
if address < 0x8000 {
// ROM data
err := bus.Cart.Write(address, value)
if err != nil {
return fmt.Errorf("Error writing to bus address %X: %s", address, err)
}
return nil
} else if address < 0xE000 {
//WRAM (Working RAM)
bus.RAM.WRAMWrite(address, value)
return nil
} else if address < 0xFF80 {
//IO Registers
IOWrite(address, value)
return nil
} else {
return fmt.Errorf("Writing to bus address %X not implemented!", address)
}
}
func (bus *Bus) Write16(address uint16, value uint16) error {
err := bus.Write(address+1, byte((value>>8)&0xFF))
if err != nil {
return err
}
err = bus.Write(address, byte(value&0xFF))
if err != nil {
return err
}
return nil
}