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