hachi

package
v0.0.0-...-1ddc78e Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2015 License: GPL-3.0 Imports: 7 Imported by: 2

Documentation

Overview

Package hachi implements various CHIP-8 utilities, including an emulator and a disassembler.

Index

Constants

View Source
const (
	Key0 = 1 << iota
	Key1
	Key2
	Key3
	Key4
	Key5
	Key6
	Key7
	Key8
	Key9
	KeyA
	KeyB
	KeyC
	KeyD
	KeyE
	KeyF
)

Key flags for the Keyboard bitfield.

Variables

View Source
var DefaultSettings = &Chip8Settings{
	MemorySize: 0x1000,
	StackSize:  12,
	Width:      64, Height: 32,
	Realistic:  true,
	LegacyMode: false,
}

The default settings for Chip8, which mimick the original CHIP-8 implementation

Key flags mapped by number.

View Source
var KeyNumbers map[uint16]uint8 = map[uint16]uint8{
	Key0: 0x00,
	Key1: 0x01,
	Key2: 0x02,
	Key3: 0x03,
	Key4: 0x04,
	Key5: 0x05,
	Key6: 0x06,
	Key7: 0x07,
	Key8: 0x08,
	Key9: 0x09,
	KeyA: 0x0A,
	KeyB: 0x0B,
	KeyC: 0x0C,
	KeyD: 0x0D,
	KeyE: 0x0E,
	KeyF: 0x0F,
}

Key numbers mapped by flag.

Functions

func RegisterDriver

func RegisterDriver(name string, drv Driver) error

RegisterDriver registers a driver to a name. The driver can then be used by setting the Driver field of Chip8 to the driver's name. This is not thread-safe, so don't call it concurrently to the emulator's execution.

func UnregisterDriver

func UnregisterDriver(name string) error

UnregisterDriver unloads a previously registered driver. This is not thread-safe, so don't call it concurrently to the emulator's execution.

Types

type AccessErr

type AccessErr struct{}

A AccessErr is returned when the program tries to access invalid or protected memory regions.

func (*AccessErr) Error

func (e *AccessErr) Error() string

type Add

type Add struct{ *RawData }

func (Add) Description

func (i Add) Description() string

func (Add) Register

func (i Add) Register() uint8

func (Add) Value

func (i Add) Value() uint8

type AddI

type AddI struct{ *RawData }

func (AddI) Description

func (i AddI) Description() string

func (AddI) Register

func (i AddI) Register() uint8

type AddRegister

type AddRegister struct{ *RawData }

func (AddRegister) Description

func (i AddRegister) Description() string

func (AddRegister) Register1

func (i AddRegister) Register1() uint8

func (AddRegister) Register2

func (i AddRegister) Register2() uint8

type And

type And struct{ *RawData }

func (And) Description

func (i And) Description() string

func (And) Register1

func (i And) Register1() uint8

func (And) Register2

func (i And) Register2() uint8

type BadCodeErr

type BadCodeErr struct{}

A BadCodeErr is returned when the emulator tries to execute invalid code.

func (*BadCodeErr) Error

func (e *BadCodeErr) Error() string

type Call

type Call struct{ *RawData }

func (Call) Address

func (i Call) Address() uint16

func (Call) Description

func (i Call) Description() string

type Chip8

type Chip8 struct {
	// The memory where programs are loaded and executed.
	// Most implementations use 4k (0x1000 bytes).
	// Programs normally start at 0x200 because the original interpreter
	// occupied those first 512 bytes.
	Memory []byte
	// V[0x0]~V[0xF] are 8-bit registers. V[0xF] doubles as a carry flag.
	V [16]uint8
	// 16-bit address register. Used for memory operations.
	I uint16
	// The call stack, which holds return addresses.
	// The original implementation allocated 48bytes for up to 12 nested calls.
	// In realistic mode, this is at 0xEA0 through 0xEAC in memory.
	Stack []uint16
	// The stack pointer. Index of the last value that was pushed on stack.
	SP int
	// Program counter. Holds the currently executing address.
	PC uint16
	// Timers. These automatically count down at 60hz when they are non-zero.
	// DT/DelayTimer is intended to be used for timing events in games, while
	// ST/SoundTimer makes a beeping sound as long as its value is non-zero.
	DT uint8
	ST uint8
	// Keyboard is a hex keyboard with 16 keys. 8, 4, 6 and 2 are typically used
	// for directional input.
	// This is a bitfield, see the constants for the flags.
	Keyboard uint16
	// Screen buffer. The official resolution is 64x32.
	// Color is monochrome, so each bit is a pixel which can be either
	// on or off.
	// Because it's stored as an array of bytes, each element holds 8 pixels and
	// the screen size must be a multiple of 8.
	// In realistic mode, this is at 0xF00 through 0xFFF in memory.
	Screen        []byte
	Width, Height uint8
	// The interval between each timer tick. The original implementation uses
	// 60hz = time.Second / 60.
	TimerInterval time.Duration
	// contains filtered or unexported fields
}

Chip8 is an implementation of a CHIP-8 emulator. It holds the state of the virtual machine and provides debugging tools.

func New

func New(driver string, s *Chip8Settings) (c *Chip8, err error)

New initializes a new instance of Chip8 with the given settings. If settings is nil, DefaultSettings will be used. driver is the name of the syscall driver that will be used.

func (*Chip8) Driver

func (c *Chip8) Driver() string

Driver returns the name of the syscall driver in use by the emulator.

func (*Chip8) GetDriverData

func (c *Chip8) GetDriverData(key string) interface{}

GetDriverData gets custom data from the currently loaded driver. Returns nil if the driver does not exist or if the data key is not found.

func (*Chip8) Load

func (c *Chip8) Load(path string) (size int64, err error)

Load opens a CHIP-8 binary file and loads it into memory. Returns the size, in bytes, of the program and an error if any.

func (*Chip8) LoadRaw

func (c *Chip8) LoadRaw(program []byte) error

LoadRaw loads a byte array as a CHIP-8 binary into memory.

func (*Chip8) Run

func (c *Chip8) Run() (err error)

Run runs the emulator, blocking the thread. Exits and returns an error if any.

func (*Chip8) String

func (c *Chip8) String() string

String returns formatted information about the instance of the emulator.

func (*Chip8) Tick

func (c *Chip8) Tick() error

Tick runs one CPU cycle, blocking the thread. Returns an error if any.

type Chip8Settings

type Chip8Settings struct {
	// Memory size. Max. 0xFFFF (65535).
	MemorySize uint16
	// Stack size. Defines the maximum amount of nested calls.
	StackSize int
	// Screen width and height in pixels. Max. 255x255.
	Width, Height uint8
	// Realistic, when enabled, makes the stack and screen buffers use the
	// same memory regions as the original implementation. This limits the
	// stack to max. 12 levels and the screen buffer to max. 2048 pixels.
	Realistic bool
	// Enables old behaviour for SHL VX,VY , SHR VX,VY , LD [I],VX and LD VX,[I]
	LegacyMode bool
}

Chip8Settings holds the configuration parameters for a Chip8 instance.

func (*Chip8Settings) Validate

func (s *Chip8Settings) Validate() error

Validate validates the settings. Returns an error when the settings aren't valid.

type Driver

type Driver interface {
	// Called before the emulator starts executing the program.
	OnInit(c *Chip8)
	// Clears the screen.
	Cls()
	// Called on every clock cycle, should be used for input polling and similar
	// tasks.
	OnUpdate(c *Chip8)
	// Called when the program modifies the screen buffer.
	UpdateScreen(c *Chip8)
	// Plays a beeping sound (this will be called every 1/60th of a second)
	Beep()
	// Returns custom data that can be retrieved through the emulator by
	// calling GetDriverData()
	GetData(key string) interface{}
	// Sets custom data that can be set through the emulator by
	// calling SetDriverData()
	SetData(key string, value interface{}) error
}

A Driver is an interface through which the emulator can perform plarform specific calls. Drivers should be registered by the RegisterDriver function in init().

type Drw

type Drw struct{ *RawData }

func (Drw) Description

func (i Drw) Description() string

func (Drw) Register1

func (i Drw) Register1() uint8

func (Drw) Register2

func (i Drw) Register2() uint8

func (Drw) Rows

func (i Drw) Rows() uint8

type Instruction

type Instruction interface {
	// Returns a detailed description of what the instruction does.
	Description() string
	// Returns a pseudo-asm representation of the instruction.
	String() string
	// Returns the instruction.
	Opcode() uint16
	// Returns the size of the instruction in bytes.
	Size() int
	// Returns the ASCII representation of the raw data for this instruction.
	// Returns an empty string if the data is not printable ascii.
	ASCII() string
	// contains filtered or unexported methods
}

An Instruction is any decompiled CHIP-8 instruction.

func DisassembleSimple

func DisassembleSimple(b []byte) (res []Instruction, err error)

DisassembleSimple disassembles raw data and return an array of instructions. It's fast but it cannot handle odd-aligned opcodes or recognize raw data memory regions. For proper disassembly, see Disassemble [to be implemented] which runs the program and analyzes it.

type Jp

type Jp struct{ *RawData }

func (Jp) Address

func (i Jp) Address() uint16

func (Jp) Description

func (i Jp) Description() string

type JpV0

type JpV0 struct{ *RawData }

func (JpV0) Address

func (i JpV0) Address() uint16

func (JpV0) Description

func (i JpV0) Description() string

type Ld

type Ld struct{ *RawData }

func (Ld) Description

func (i Ld) Description() string

func (Ld) Register

func (i Ld) Register() uint8

func (Ld) Value

func (i Ld) Value() uint8

type LdBcd

type LdBcd struct{ *RawData }

func (LdBcd) Description

func (i LdBcd) Description() string

func (LdBcd) Register

func (i LdBcd) Register() uint8

type LdDelayTimer

type LdDelayTimer struct{ *RawData }

func (LdDelayTimer) Description

func (i LdDelayTimer) Description() string

func (LdDelayTimer) Register

func (i LdDelayTimer) Register() uint8

type LdFont

type LdFont struct{ *RawData }

func (LdFont) Description

func (i LdFont) Description() string

func (LdFont) Register

func (i LdFont) Register() uint8

type LdI

type LdI struct{ *RawData }

func (LdI) Description

func (i LdI) Description() string

func (LdI) Value

func (i LdI) Value() uint16

type LdKeyboard

type LdKeyboard struct{ *RawData }

func (LdKeyboard) Description

func (i LdKeyboard) Description() string

func (LdKeyboard) Register

func (i LdKeyboard) Register() uint8

type LdMemory

type LdMemory struct{ *RawData }

func (LdMemory) Description

func (i LdMemory) Description() string

func (LdMemory) Register

func (i LdMemory) Register() uint8

type LdRegister

type LdRegister struct{ *RawData }

func (LdRegister) Description

func (i LdRegister) Description() string

func (LdRegister) Register1

func (i LdRegister) Register1() uint8

func (LdRegister) Register2

func (i LdRegister) Register2() uint8

type LdSetDelayTimer

type LdSetDelayTimer struct{ *RawData }

func (LdSetDelayTimer) Description

func (i LdSetDelayTimer) Description() string

func (LdSetDelayTimer) Register

func (i LdSetDelayTimer) Register() uint8

type LdSetMemory

type LdSetMemory struct{ *RawData }

func (LdSetMemory) Description

func (i LdSetMemory) Description() string

func (LdSetMemory) Register

func (i LdSetMemory) Register() uint8

type LdSetSoundTimer

type LdSetSoundTimer struct{ *RawData }

func (LdSetSoundTimer) Description

func (i LdSetSoundTimer) Description() string

func (LdSetSoundTimer) Register

func (i LdSetSoundTimer) Register() uint8

type NullDriver

type NullDriver struct{ Driver }

A NullDriver is the default driver, which ignores all calls.

func (NullDriver) Beep

func (d NullDriver) Beep()

func (NullDriver) Cls

func (d NullDriver) Cls()

func (NullDriver) GetData

func (d NullDriver) GetData(key string) interface{}

func (NullDriver) OnInit

func (d NullDriver) OnInit(c *Chip8)

func (NullDriver) OnUpdate

func (d NullDriver) OnUpdate(c *Chip8)

func (NullDriver) SetData

func (d NullDriver) SetData(key string, value interface{}) error

func (NullDriver) UpdateScreen

func (d NullDriver) UpdateScreen(c *Chip8)

type Or

type Or struct{ *RawData }

func (Or) Description

func (i Or) Description() string

func (Or) Register1

func (i Or) Register1() uint8

func (Or) Register2

func (i Or) Register2() uint8

type OutOfMemoryErr

type OutOfMemoryErr struct {
	Instance    *Chip8
	ProgramSize int64
}

An OutOfMemoryErr is returned upon attempting to load a program that exceeds the memory's capacity.

func (*OutOfMemoryErr) Error

func (e *OutOfMemoryErr) Error() string

type OverflowErr

type OverflowErr struct{}

A OverflowErr is returned when an overflow occurs during an instruction.

func (*OverflowErr) Error

func (e *OverflowErr) Error() string

type RawData

type RawData struct {
	Instruction
	// contains filtered or unexported fields
}

RawData holds 1 or 2 bytes of unrecognized raw data

func (RawData) ASCII

func (i RawData) ASCII() (res string)

func (RawData) Description

func (i RawData) Description() string

func (RawData) Opcode

func (i RawData) Opcode() (res uint16)

Opcode returns the data as a 16-bit integer. Normally, this function is used to get the opcode for an instruction, but RawData is a special case in which this function is not used.

func (RawData) Size

func (i RawData) Size() int

func (RawData) String

func (i RawData) String() string

type Rnd

type Rnd struct{ *RawData }

func (Rnd) Description

func (i Rnd) Description() string

func (Rnd) Register

func (i Rnd) Register() uint8

func (Rnd) Value

func (i Rnd) Value() uint8

type Se

type Se struct{ *RawData }

func (Se) Description

func (i Se) Description() string

func (Se) Register

func (i Se) Register() uint8

func (Se) Value

func (i Se) Value() uint8

type SeRegister

type SeRegister struct{ *RawData }

func (SeRegister) Description

func (i SeRegister) Description() string

func (SeRegister) Register1

func (i SeRegister) Register1() uint8

func (SeRegister) Register2

func (i SeRegister) Register2() uint8

type Shl

type Shl struct{ *RawData }

func (Shl) Description

func (i Shl) Description() string

func (Shl) Register1

func (i Shl) Register1() uint8

func (Shl) Register2

func (i Shl) Register2() uint8

type Shr

type Shr struct{ *RawData }

func (Shr) Description

func (i Shr) Description() string

func (Shr) Register1

func (i Shr) Register1() uint8

func (Shr) Register2

func (i Shr) Register2() uint8

type Sknp

type Sknp struct{ *RawData }

func (Sknp) Description

func (i Sknp) Description() string

func (Sknp) Register

func (i Sknp) Register() uint8

type Skp

type Skp struct{ *RawData }

func (Skp) Description

func (i Skp) Description() string

func (Skp) Register

func (i Skp) Register() uint8

type Sne

type Sne struct{ *RawData }

func (Sne) Description

func (i Sne) Description() string

func (Sne) Register

func (i Sne) Register() uint8

func (Sne) Value

func (i Sne) Value() uint8

type SneRegister

type SneRegister struct{ *RawData }

func (SneRegister) Description

func (i SneRegister) Description() string

func (SneRegister) Register1

func (i SneRegister) Register1() uint8

func (SneRegister) Register2

func (i SneRegister) Register2() uint8

type StackOverflowErr

type StackOverflowErr struct{}

An StackOverflowErr is returned when the stack pointer exceeds the stack.

func (*StackOverflowErr) Error

func (e *StackOverflowErr) Error() string

type SubRegister

type SubRegister struct{ *RawData }

func (SubRegister) Description

func (i SubRegister) Description() string

func (SubRegister) Register1

func (i SubRegister) Register1() uint8

func (SubRegister) Register2

func (i SubRegister) Register2() uint8

type Subn

type Subn struct{ *RawData }

func (Subn) Description

func (i Subn) Description() string

func (Subn) Register1

func (i Subn) Register1() uint8

func (Subn) Register2

func (i Subn) Register2() uint8

type Sys

type Sys struct{ *RawData }

func (Sys) Address

func (i Sys) Address() uint16

func (Sys) Description

func (i Sys) Description() string

type Xor

type Xor struct{ *RawData }

func (Xor) Description

func (i Xor) Description() string

func (Xor) Register1

func (i Xor) Register1() uint8

func (Xor) Register2

func (i Xor) Register2() uint8

Jump to

Keyboard shortcuts

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