Documentation ¶
Overview ¶
Package chip8 provides a Go implementation of the CHIP-8 emulator.
CHIP-8 is an interpreted programming language, developed by Joseph Weisbecker. It was initially used on the COSMAC VIP and Telmac 1800 8-bit microcomputers in the mid-1970s. CHIP-8 programs are run on a CHIP-8 virtual machine. It was made to allow video games to be more easily programmed for said computers.
This package provides a Go implementation that can run CHIP-8 binaries.
Index ¶
Constants ¶
const ( GraphicsWidth = 64 // Pixels GraphicsHeight = 32 // Pixels )
Variables ¶
var ( // DefaultKeypad is the default Keypad to use for input. The default is // to always return 0x01. DefaultKeypad Keypad = NullKeypad // DefaultDisplay is the default Display to render graphics data to. DefaultDisplay Display = NullDisplay // DefaultLogger is the default logger to use. Defaults to logging to /dev/null DefaultLogger = log.New(ioutil.Discard, "", 0) // DefaultClockSpeed is the default clock speed of the CPU. The CHIP-8 // operated at 60 Hz. DefaultClockSpeed = time.Duration(60) // Hz // DefaultOptions is the default set of options that's used when calling // NewCPU. DefaultOptions = &Options{ ClockSpeed: DefaultClockSpeed, } )
Sensible defaults
var ( // ErrQuit is returned by Keypads to indicate a shutdown. ErrQuit = errors.New("chip8: shutting down") )
var FontSet = []byte{
0xF0, 0x90, 0x90, 0x90, 0xF0,
0x20, 0x60, 0x20, 0x20, 0x70,
0xF0, 0x10, 0xF0, 0x80, 0xF0,
0xF0, 0x10, 0xF0, 0x10, 0xF0,
0x90, 0x90, 0xF0, 0x10, 0x10,
0xF0, 0x80, 0xF0, 0x10, 0xF0,
0xF0, 0x80, 0xF0, 0x90, 0xF0,
0xF0, 0x10, 0x20, 0x40, 0x40,
0xF0, 0x90, 0xF0, 0x90, 0xF0,
0xF0, 0x90, 0xF0, 0x10, 0xF0,
0xF0, 0x90, 0xF0, 0x90, 0x90,
0xE0, 0x90, 0xE0, 0x90, 0xE0,
0xF0, 0x80, 0x80, 0x80, 0xF0,
0xE0, 0x90, 0x90, 0x90, 0xE0,
0xF0, 0x80, 0xF0, 0x80, 0xF0,
0xF0, 0x80, 0xF0, 0x80, 0x80,
}
CHIP-8 Font Set.
var NullDisplay = DisplayFunc(func(*Graphics) error { return nil })
NullDisplay is an implementation of the Display interface that does nothing.
var NullKeypad = KeypadFunc(func() (byte, error) { return 0x00, errors.New("null keypad not usable") })
NullKeypad is a Keypad that just returns an error.
Functions ¶
This section is empty.
Types ¶
type CPU ¶
type CPU struct { // The 4096 bytes of memory. // // Memory Map: // +---------------+= 0xFFF (4095) End of Chip-8 RAM // | | // | | // | | // | | // | | // | 0x200 to 0xFFF| // | Chip-8 | // | Program / Data| // | Space | // | | // | | // | | // +- - - - - - - -+= 0x600 (1536) Start of ETI 660 Chip-8 programs // | | // | | // | | // +---------------+= 0x200 (512) Start of most Chip-8 programs // | 0x000 to 0x1FF| // | Reserved for | // | interpreter | // +---------------+= 0x000 (0) Start of Chip-8 RAM Memory [4096]byte // The address register, which is named I, is 16 bits wide and is used // with several opcodes that involve memory operations. I uint16 // Program counter. PC uint16 // CHIP-8 has 16 8-bit data registers named from V0 to VF. The VF // register doubles as a carry flag. V [16]byte // The stack is only used to store return addresses when subroutines are // called. The original 1802 version allocated 48 bytes for up to 12 // levels of nesting; modern implementations normally have at least 16 // levels. Stack [16]uint16 // Stack pointer. SP byte // The CHIP-8 timers count down at 60 Hz, so we slow down the cpu clock // to only execute 60 opcodes per second. Clock <-chan time.Time // Delay timer. DT byte // Sound timer. ST byte // The graphics array. Graphics // The connected Keypad. The zero value is the DefaultKeypad. Keypad Keypad // A logger to log information about the CPU while it's executing. The // zero value is the DefaultLogger. Logger *log.Logger // contains filtered or unexported fields }
CPU represents a CHIP-8 CPU.
func (*CPU) Load ¶
Load reads from the reader and loads the bytes into memory starting at address 200.
type Display ¶
type Display interface { // Render should render the current graphics array to the display. Render(*Graphics) error }
Display represents the output display for the CHIP-8 graphics array.
type DisplayFunc ¶
func (DisplayFunc) Render ¶
func (f DisplayFunc) Render(g *Graphics) error
type Graphics ¶
type Graphics struct { // The raw pixels of the graphics array. Pixels [GraphicsWidth * GraphicsHeight]byte // The display to render to. The nil value is the DefaultDisplay. Display }
Graphics represents the graphics array for the CHIP-8.
type Keypad ¶
type Keypad interface { // ReadByte waits for input on the keyboard and returns the key that was // pressed. ReadByte() (byte, error) }
Keypad represents a CHIP-8 Keypad.
type KeypadFunc ¶
Keypad func can be used to wrap a function that returns a byte as a Keypad.
func (KeypadFunc) ReadByte ¶
func (f KeypadFunc) ReadByte() (byte, error)
type TermboxDisplay ¶
type TermboxDisplay struct {
// contains filtered or unexported fields
}
TermboxDisplay is an implementation of the Display interface that renders the graphics array to the terminal.
func NewTermboxDisplay ¶
func NewTermboxDisplay(fg, bg termbox.Attribute) (*TermboxDisplay, error)
NewTermboxDisplay returns a new TermboxDisplay instance.
func (*TermboxDisplay) Close ¶
func (d *TermboxDisplay) Close()
func (*TermboxDisplay) Render ¶
func (d *TermboxDisplay) Render(g *Graphics) error
Render renders the graphics array to the terminal using Termbox.
type TermboxKeypad ¶
type TermboxKeypad struct{}
TermboxKeypad is a Keypad implementation that maps keys from a standard keyboard to the CHIP-8 keyboard and uses termbox to poll for events.
func NewTermboxKeypad ¶
func NewTermboxKeypad() *TermboxKeypad
func (*TermboxKeypad) ReadByte ¶
func (k *TermboxKeypad) ReadByte() (byte, error)
Get waits for a keypress.
type UnknownOpcode ¶
type UnknownOpcode struct {
Opcode uint16
}
UnknownOpcode is return when the opcode is not recognized.
func (*UnknownOpcode) Error ¶
func (e *UnknownOpcode) Error() string