chip8

package module
v0.0.0-...-66679af Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2018 License: MIT Imports: 9 Imported by: 1

README

CHIP-8 Build Status

Godoc

CHIP-8 emulator written in Go.

Usage

This comes with a chip8 package that can be used as a library for executing CHIP-8 binary programs, and also a chip8 reference command.

You can install it with:

$ go install -u github.com/ejholmes/chip8/cmd/chip8

And run a binary like so:

$ chip8 run myprog.ch8

The default display implementation uses go-termbox so the program runs entirely inside your terminal.

Reference

http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/ http://devernay.free.fr/hacks/chip8/C8TECH10.HTM

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

View Source
const (
	GraphicsWidth  = 64 // Pixels
	GraphicsHeight = 32 // Pixels
)

Variables

View Source
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

View Source
var (
	// ErrQuit is returned by Keypads to indicate a shutdown.
	ErrQuit = errors.New("chip8: shutting down")
)
View Source
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.

View Source
var NullDisplay = DisplayFunc(func(*Graphics) error {
	return nil
})

NullDisplay is an implementation of the Display interface that does nothing.

View Source
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 NewCPU

func NewCPU(options *Options) (*CPU, error)

NewCPU returns a new CPU instance.

func (*CPU) Dispatch

func (c *CPU) Dispatch(op uint16) error

Dispatch executes the given opcode.

func (*CPU) Load

func (c *CPU) Load(r io.Reader) (int, error)

Load reads from the reader and loads the bytes into memory starting at address 200.

func (*CPU) LoadBytes

func (c *CPU) LoadBytes(p []byte) (int, error)

LoadBytes loads the bytes into memory.

func (*CPU) Run

func (c *CPU) Run() error

Run does the thing.

func (*CPU) Step

func (c *CPU) Step() (uint16, error)

Step runs a single CPU cycle.

func (*CPU) Stop

func (c *CPU) Stop()

Stop stops the CPU from executing.

func (*CPU) String

func (c *CPU) String() string

String implements the fmt.Stringer interface.

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

type DisplayFunc func(*Graphics) error

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.

func (*Graphics) Clear

func (g *Graphics) Clear()

Clear clears the display.

func (*Graphics) Draw

func (g *Graphics) Draw() error

Draw draws the graphics array to the Display.

func (*Graphics) EachPixel

func (g *Graphics) EachPixel(fn func(x, y uint16, addr int))

EachPixel yields each pixel in the graphics array to fn.

func (*Graphics) Set

func (g *Graphics) Set(x, y uint16, on bool) (collision bool)

Set turns the pixel at the given coordinates on or off. If there's a collision, it returns true.

func (*Graphics) WriteSprite

func (g *Graphics) WriteSprite(sprite []byte, x, y byte) (collision bool)

DrawSprite draws a sprite to the graphics array starting at coording x, y. If there is a collision, WriteSprite returns true.

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

type KeypadFunc func() (byte, error)

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 Options

type Options struct {
	ClockSpeed time.Duration
}

Options provides a means of configuring the CPU.

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

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL