Documentation ¶
Overview ¶
Package cpu implements a 6502 CPU instruction set and emulator.
Index ¶
- Constants
- Variables
- type Architecture
- type Breakpoint
- type BreakpointHandler
- type BrkHandler
- type CPU
- func (cpu *CPU) AttachBrkHandler(handler BrkHandler)
- func (cpu *CPU) AttachDebugger(debugger *Debugger)
- func (cpu *CPU) DetachDebugger()
- func (cpu *CPU) GetAllMemory(addr uint16) string
- func (cpu *CPU) GetInstruction(addr uint16) *Instruction
- func (cpu *CPU) GetRegisters() string
- func (cpu *CPU) GetStack() string
- func (cpu *CPU) NextAddr(addr uint16) uint16
- func (cpu *CPU) SetPC(addr uint16)
- func (cpu *CPU) Step()
- type DataBreakpoint
- type Debugger
- func (d *Debugger) AddBreakpoint(addr uint16) *Breakpoint
- func (d *Debugger) AddConditionalDataBreakpoint(addr uint16, value byte)
- func (d *Debugger) AddDataBreakpoint(addr uint16) *DataBreakpoint
- func (d *Debugger) GetBreakpoint(addr uint16) *Breakpoint
- func (d *Debugger) GetBreakpoints() []*Breakpoint
- func (d *Debugger) GetDataBreakpoint(addr uint16) *DataBreakpoint
- func (d *Debugger) GetDataBreakpoints() []*DataBreakpoint
- func (d *Debugger) RemoveBreakpoint(addr uint16)
- func (d *Debugger) RemoveDataBreakpoint(addr uint16)
- type FlatMemory
- func (m *FlatMemory) LoadAddress(addr uint16) uint16
- func (m *FlatMemory) LoadByte(addr uint16) byte
- func (m *FlatMemory) LoadBytes(addr uint16, b []byte)
- func (m *FlatMemory) StoreAddress(addr uint16, v uint16)
- func (m *FlatMemory) StoreByte(addr uint16, v byte)
- func (m *FlatMemory) StoreBytes(addr uint16, b []byte)
- type Instruction
- type InstructionSet
- type Memory
- type Mode
- type Registers
Constants ¶
const ( CarryBit = 1 << 0 ZeroBit = 1 << 1 InterruptDisableBit = 1 << 2 DecimalBit = 1 << 3 BreakBit = 1 << 4 ReservedBit = 1 << 5 OverflowBit = 1 << 6 SignBit = 1 << 7 )
Bits assigned to the processor status byte
Variables ¶
var (
ErrMemoryOutOfBounds = errors.New("Memory access out of bounds")
)
Errors
Functions ¶
This section is empty.
Types ¶
type Architecture ¶
type Architecture byte
Architecture selects the CPU chip: 6502 or 65c02
const ( // NMOS 6502 CPU NMOS Architecture = iota // CMOS 65c02 CPU CMOS )
type Breakpoint ¶
type Breakpoint struct { Address uint16 // address of execution breakpoint Disabled bool // this breakpoint is currently disabled }
A Breakpoint represents an address that will cause the debugger to stop code execution when the program counter reaches it.
type BreakpointHandler ¶
type BreakpointHandler interface { OnBreakpoint(cpu *CPU, b *Breakpoint) OnDataBreakpoint(cpu *CPU, b *DataBreakpoint) }
The BreakpointHandler interface should be implemented by any object that wishes to receive debugger breakpoint notifications.
type BrkHandler ¶
type BrkHandler interface {
OnBrk(cpu *CPU)
}
BrkHandler is an interface implemented by types that wish to be notified when a BRK instruction is about to be executed.
type CPU ¶
type CPU struct { Arch Architecture // CPU architecture Reg Registers // CPU registers Mem Memory // assigned memory Cycles uint64 // total executed CPU cycles LastPC uint16 // Previous program counter InstSet *InstructionSet // Instruction set used by the CPU // contains filtered or unexported fields }
CPU represents a single 6502 CPU. It contains a pointer to the memory associated with the CPU.
func NewCPU ¶
func NewCPU(arch Architecture, m Memory) *CPU
NewCPU creates an emulated 6502 CPU bound to the specified memory.
func (*CPU) AttachBrkHandler ¶
func (cpu *CPU) AttachBrkHandler(handler BrkHandler)
AttachBrkHandler attaches a handler that is called whenever the BRK instruction is executed.
func (*CPU) AttachDebugger ¶
AttachDebugger attaches a debugger to the CPU. The debugger receives notifications whenever the CPU executes an instruction or stores a byte to memory.
func (*CPU) DetachDebugger ¶
func (cpu *CPU) DetachDebugger()
DetachDebugger detaches the currently debugger from the CPU.
func (*CPU) GetAllMemory ¶
GetAllMemory returns a 16 byte formatted string starting at 0000
func (*CPU) GetInstruction ¶
func (cpu *CPU) GetInstruction(addr uint16) *Instruction
GetInstruction returns the instruction opcode at the requested address.
func (*CPU) GetRegisters ¶
GetRegisters returns a formatted string of register values
func (*CPU) GetStack ¶
GetStack returns a formatted string of bytes beginning at SP down to to of stack 6502 stack grows from $01FF down to $0000
func (*CPU) NextAddr ¶
NextAddr returns the address of the next instruction following the instruction at addr.
type DataBreakpoint ¶
type DataBreakpoint struct { Address uint16 // breakpoint triggered by stores to this address Disabled bool // this breakpoint is currently disabled Conditional bool // this breakpoint is conditional on a certain Value being stored Value byte // the value that must be stored if the breakpoint is conditional }
A DataBreakpoint represents an address that will cause the debugger to stop executing code when a byte is stored to it.
type Debugger ¶
type Debugger struct {
// contains filtered or unexported fields
}
The Debugger interface may be implemented to intercept instructions before and after they are executed on the emulated CPU.
func NewDebugger ¶
func NewDebugger(breakpointHandler BreakpointHandler) *Debugger
NewDebugger creates a new CPU debugger.
func (*Debugger) AddBreakpoint ¶
func (d *Debugger) AddBreakpoint(addr uint16) *Breakpoint
AddBreakpoint adds a new breakpoint address to the debugger. If the breakpoint was already set, the request is ignored.
func (*Debugger) AddConditionalDataBreakpoint ¶
AddConditionalDataBreakpoint adds a conditional data breakpoint on the requested address.
func (*Debugger) AddDataBreakpoint ¶
func (d *Debugger) AddDataBreakpoint(addr uint16) *DataBreakpoint
AddDataBreakpoint adds an unconditional data breakpoint on the requested address.
func (*Debugger) GetBreakpoint ¶
func (d *Debugger) GetBreakpoint(addr uint16) *Breakpoint
GetBreakpoint looks up a breakpoint by address and returns it if found. Otherwise it returns nil.
func (*Debugger) GetBreakpoints ¶
func (d *Debugger) GetBreakpoints() []*Breakpoint
GetBreakpoints returns all breakpoints currently set in the debugger.
func (*Debugger) GetDataBreakpoint ¶
func (d *Debugger) GetDataBreakpoint(addr uint16) *DataBreakpoint
GetDataBreakpoint looks up a data breakpoint on the provided address and returns it if found. Otherwise it returns nil.
func (*Debugger) GetDataBreakpoints ¶
func (d *Debugger) GetDataBreakpoints() []*DataBreakpoint
GetDataBreakpoints returns all data breakpoints currently set in the debugger.
func (*Debugger) RemoveBreakpoint ¶
RemoveBreakpoint removes a breakpoint from the debugger.
func (*Debugger) RemoveDataBreakpoint ¶
RemoveDataBreakpoint removes a (conditional or unconditional) data breakpoint at the requested address.
type FlatMemory ¶
type FlatMemory struct {
// contains filtered or unexported fields
}
FlatMemory represents an entire 16-bit address space as a singular 64K buffer.
func NewFlatMemory ¶
func NewFlatMemory() *FlatMemory
NewFlatMemory creates a new 16-bit memory space.
func (*FlatMemory) LoadAddress ¶
func (m *FlatMemory) LoadAddress(addr uint16) uint16
LoadAddress loads a 16-bit address value from the requested address and returns it.
When the address spans 2 pages (i.e., address ends in 0xff), the low byte of the loaded address comes from a page-wrapped address. For example, LoadAddress on $12FF reads the low byte from $12FF and the high byte from $1200. This mimics the behavior of the NMOS 6502.
func (*FlatMemory) LoadByte ¶
func (m *FlatMemory) LoadByte(addr uint16) byte
LoadByte loads a single byte from the address and returns it.
func (*FlatMemory) LoadBytes ¶
func (m *FlatMemory) LoadBytes(addr uint16, b []byte)
LoadBytes loads multiple bytes from the address and returns them.
func (*FlatMemory) StoreAddress ¶
func (m *FlatMemory) StoreAddress(addr uint16, v uint16)
StoreAddress stores a 16-bit address value to the requested address.
func (*FlatMemory) StoreByte ¶
func (m *FlatMemory) StoreByte(addr uint16, v byte)
StoreByte stores a byte at the requested address.
func (*FlatMemory) StoreBytes ¶
func (m *FlatMemory) StoreBytes(addr uint16, b []byte)
StoreBytes stores multiple bytes to the requested address.
type Instruction ¶
type Instruction struct { Name string // all-caps name of the instruction Mode Mode // addressing mode Opcode byte // hexadecimal opcode value Length byte // combined size of opcode and operand, in bytes Cycles byte // number of CPU cycles to execute the instruction BPCycles byte // additional cycles required if boundary page crossed // contains filtered or unexported fields }
An Instruction describes a CPU instruction, including its name, its addressing mode, its opcode value, its operand size, and its CPU cycle cost.
type InstructionSet ¶
type InstructionSet struct { Arch Architecture // contains filtered or unexported fields }
An InstructionSet defines the set of all possible instructions that can run on the emulated CPU.
func GetInstructionSet ¶
func GetInstructionSet(arch Architecture) *InstructionSet
GetInstructionSet returns an instruction set for the requested CPU architecture.
func (*InstructionSet) GetInstructions ¶
func (s *InstructionSet) GetInstructions(name string) []*Instruction
GetInstructions returns all CPU instructions whose name matches the provided string.
func (*InstructionSet) Lookup ¶
func (s *InstructionSet) Lookup(opcode byte) *Instruction
Lookup retrieves a CPU instruction corresponding to the requested opcode.
type Memory ¶
type Memory interface { // LoadByte loads a single byte from the address and returns it. LoadByte(addr uint16) byte // LoadBytes loads multiple bytes from the address and stores them into // the buffer 'b'. LoadBytes(addr uint16, b []byte) // LoadAddress loads a 16-bit address value from the requested address and // returns it. LoadAddress(addr uint16) uint16 // StoreByte stores a byte to the requested address. StoreByte(addr uint16, v byte) // StoreBytes stores multiple bytes to the requested address. StoreBytes(addr uint16, b []byte) // StoreAddres stores a 16-bit address 'v' to the requested address. StoreAddress(addr uint16, v uint16) }
The Memory interface presents an interface to the CPU through which all memory accesses occur.
type Mode ¶
type Mode byte
Mode describes a memory addressing mode.
const ( IMM Mode = iota // Immediate IMP // Implied (no operand) REL // Relative ZPG // Zero Page ZPX // Zero Page,X ZPY // Zero Page,Y ABS // Absolute ABX // Absolute,X ABY // Absolute,Y IND // (Indirect) IDX // (Indirect,X) IDY // (Indirect),Y ACC // Accumulator (no operand) )
All possible memory addressing modes
type Registers ¶
type Registers struct { A byte // accumulator X byte // X indexing register Y byte // Y indexing register SP byte // stack pointer ($100 + SP = stack memory location) PC uint16 // program counter Carry bool // PS: Carry bit Zero bool // PS: Zero bit InterruptDisable bool // PS: Interrupt disable bit Decimal bool // PS: Decimal bit Overflow bool // PS: Overflow bit Sign bool // PS: Sign bit }
Registers contains the state of all 6502 registers.
func (*Registers) Init ¶
func (r *Registers) Init()
Init initializes all registers. A, X, Y = 0. SP = 0xff. PC = 0. PS = 0.