Documentation ¶
Overview ¶
Package hachi implements various CHIP-8 utilities, including an emulator and a disassembler.
Index ¶
- Constants
- Variables
- func RegisterDriver(name string, drv Driver) error
- func UnregisterDriver(name string) error
- type AccessErr
- type Add
- type AddI
- type AddRegister
- type And
- type BadCodeErr
- type Call
- type Chip8
- type Chip8Settings
- type Driver
- type Drw
- type Instruction
- type Jp
- type JpV0
- type Ld
- type LdBcd
- type LdDelayTimer
- type LdFont
- type LdI
- type LdKeyboard
- type LdMemory
- type LdRegister
- type LdSetDelayTimer
- type LdSetMemory
- type LdSetSoundTimer
- type NullDriver
- type Or
- type OutOfMemoryErr
- type OverflowErr
- type RawData
- type Rnd
- type Se
- type SeRegister
- type Shl
- type Shr
- type Sknp
- type Skp
- type Sne
- type SneRegister
- type StackOverflowErr
- type SubRegister
- type Subn
- type Sys
- type Xor
Constants ¶
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 ¶
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
var KeyFlags []uint16 = []uint16{Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8, Key9, KeyA, KeyB, KeyC, KeyD, KeyE, KeyF}
Key flags mapped by number.
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 ¶
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 ¶
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.
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 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 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) GetDriverData ¶
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 ¶
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.
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 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 LdDelayTimer ¶
type LdDelayTimer struct{ *RawData }
func (LdDelayTimer) Description ¶
func (i LdDelayTimer) Description() string
func (LdDelayTimer) Register ¶
func (i LdDelayTimer) Register() uint8
type LdKeyboard ¶
type LdKeyboard struct{ *RawData }
func (LdKeyboard) Description ¶
func (i LdKeyboard) Description() string
func (LdKeyboard) Register ¶
func (i LdKeyboard) 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 OutOfMemoryErr ¶
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) Description ¶
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 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