sim6502

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2023 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package sim6502 provides a 6502 processor simulator

Index

Constants

View Source
const StackLocation uint16 = 0x0100 // Base of stack

StackLocation points to the base of the stack at 0x0100 N.B. Stack grows down from PTR=0xff (i.e. 0x01FF)

Variables

View Source
var IllegalInstructionMagicConstant uint8 = 0x00

Because ANE is highly unstable, operation depends on a constant which may vary depending on chip series, temperature and so forth change the constant if you want ref: https://www.masswerk.at/6502/6502_instruction_set.html#ANE

View Source
var StackDebug = false

StackDebug can be set to true to output messages when stack operations occur strictly for debugging

Functions

func FormatInstruction

func FormatInstruction(pc uint16, ins *instruction, b1 uint8, b2 uint8, ma uint16, mc uint8, spre string, cycles uint8, proc *Processor) string

func GetVector

func GetVector(mem Memory, vector SystemVector) uint16

GetVector will return the memory address in the specified vector

func SetVector

func SetVector(mem Memory, vector SystemVector, addr uint16)

Types

type AddressingMode

type AddressingMode int
const (
	A AddressingMode = iota
	ABS
	ABS_X
	ABS_Y
	IMMED
	IMPL
	IND
	X_IND
	IND_Y
	REL
	ZPG
	ZPG_X
	ZPG_Y
	ZPG_REL   // 65C02 only
	IND_ABS_X // 65C02 only
	ZPG_IND   //65C02 only
)

func (AddressingMode) String

func (mode AddressingMode) String() string

type BreakpointHandler

type BreakpointHandler interface {

	// HandleBreak will be called when the PC reaches the listed brekapoint address
	// but before that instruction is executed
	// The current processor state is passed to the handler for inspection and, if desired,
	// modification
	HandleBreak(proc *Processor) error
}

BreakpointHandler defines the interface to be implemented by the user when implementing a breakpoint

type BreakpointHandlerDisableTrace

type BreakpointHandlerDisableTrace struct{}

BreakpointHandlerDisableTrace is a provided breakpoint handler that will disable trace when the breakpoint is reached

func (*BreakpointHandlerDisableTrace) HandleBreak

func (b *BreakpointHandlerDisableTrace) HandleBreak(proc *Processor)

type BreakpointHandlerEnableTrace

type BreakpointHandlerEnableTrace struct{}

BreakpointHandlerEnableTrace is a provided breakpoint handler that will enable trace when the breakpoint is reached

func (*BreakpointHandlerEnableTrace) HandleBreak

func (b *BreakpointHandlerEnableTrace) HandleBreak(proc *Processor)

type MappableMemory

type MappableMemory struct {
	// contains filtered or unexported fields
}

MappableMemory is a raw 64K address space in which you may map additional handlers to provide either read or write functionality at specific addresses

func (*MappableMemory) Clear

func (m *MappableMemory) Clear()

Clear clears the memory

func (*MappableMemory) DisableReadDebugging

func (m *MappableMemory) DisableReadDebugging()

DisableReadDebugging will disable debugging of reads

func (*MappableMemory) DisableWriteDebugging

func (m *MappableMemory) DisableWriteDebugging()

DisableWriteDebugging will disable debugging of writes

func (*MappableMemory) EnableReadDebugging

func (m *MappableMemory) EnableReadDebugging(w io.Writer)

EnableReadDebugging will report every read to the provided writer

func (*MappableMemory) EnableWriteDebugging

func (m *MappableMemory) EnableWriteDebugging(w io.Writer)

EnableWriteDebugging will report every write to the provided writer

func (*MappableMemory) Map

func (m *MappableMemory) Map(handler MappedMemoryHandler)

Map will map a new handler into the memory space The MappedMemoryHandler must implement either or both of MappedMemoryReadHandler and/or MappedMemoryWriteHandler otherwise it won't do anything

func (*MappableMemory) Read

func (m *MappableMemory) Read(location uint16) uint8

Read memory

func (*MappableMemory) Write

func (m *MappableMemory) Write(location uint16, value uint8)

Write memory

type MappedMemoryAddressRange

type MappedMemoryAddressRange struct {
	Start, End uint16
}

MappedMemoryAddressRange provides an address range used for mapping memory Start must be <= End

type MappedMemoryHandler

type MappedMemoryHandler interface {
	// AddressRange reports the memory mapped address range supported by the device
	AddressRange() []MappedMemoryAddressRange
}

MappedMemoryHandler represents an implementation of a memory mapped device

type MappedMemoryReadHandler

type MappedMemoryReadHandler interface {
	MappedMemoryHandler
	// Read is called when the CPU reads the specified
	Read(addr uint16) uint8
}

MappedMemoryReadHandler is a mapped device that receives provides data to the CPU when it's memory location(s) are read

type MappedMemoryWriteHandler

type MappedMemoryWriteHandler interface {
	MappedMemoryHandler
	// Write is called when the CPU writes to the specified address
	Write(addr uint16, val uint8)
}

MappedMemoryWriteHandler is a mapped device that received writes from the CPU to it's memory location(s)

type Memory

type Memory interface {
	// Read reads a byte from the specified address
	Read(addr uint16) uint8

	// Write writes a byte to the specified address
	Write(addr uint16, value uint8)

	// Clear must clear all memory to zero value
	Clear()
}

Memory is the interface that must be implemented by any memory provider The memory provider should implement the entire 64K address space as it sees fit

type Processor

type Processor struct {
	// contains filtered or unexported fields
}

Processor represents a 6502 series processor Always create a new processor instance with NewProcessor() function

func NewProcessor

func NewProcessor(m Memory) *Processor

NewProcessor returns a new, properly initialized 6502 processor

func (*Processor) ClearBreakpoints

func (p *Processor) ClearBreakpoints() *Processor

ClearBreakpoints will clear all previously defined breakpoints Call only when the processor is stopped

func (*Processor) DumpState

func (p *Processor) DumpState(w io.Writer)

DumpState can be used to output the current processor state to a writer

func (*Processor) GetLastRunPerformance

func (p *Processor) GetLastRunPerformance() ProcessorPerformance

GetLastRunPerformance will return a performance report that can be used to evaluate the last run of the processor

func (*Processor) IRQ

func (p *Processor) IRQ(state bool)

IRQ sets the state of the IRQ line (true, triggered, false, clear)

func (*Processor) Init

func (p *Processor) Init() *Processor

Init will initialite the processor, clearing memory, registers and unsetting any breakpoints

func (*Processor) IsIRQSet

func (p *Processor) IsIRQSet() bool

IsIRQSet returns true if the IRQ line is set (low)

func (*Processor) IsResetSet

func (p *Processor) IsResetSet() bool

IsResetSet returns true if the simulated reset line is pulled low

func (*Processor) Load

func (p *Processor) Load(r io.ByteReader, start uint16) *Processor

Load is used to load raw binary content into the processor at the indicated start location

func (*Processor) LoadHex

func (p *Processor) LoadHex(r io.Reader) *Processor

LoadHex is used to load an intel .hex file into the processor

func (*Processor) LoadIllegalInstructions

func (p *Processor) LoadIllegalInstructions() *Processor

LoadIllegalInstructions will provide support for undocumented/unofficial/illegal instruction set

func (*Processor) Memory

func (p *Processor) Memory() Memory

Memory can be used to retrieve a copy of the current memory implementation

func (*Processor) NMI

func (p *Processor) NMI(state bool) error

func (*Processor) Registers

func (p *Processor) Registers() *Registers

Registers can be used to retrieve a copy of the current processor registers

func (*Processor) Reset

func (p *Processor) Reset(state bool)

Reset simulates the reset line being pulled low (state = true) or not (state = false) To reset the processor you have to pull it (state = true) and then set back to high after a few cycles, otherwise it will be missed

func (*Processor) RunFrom

func (p *Processor) RunFrom(addr uint16) (err error)

RunFrom will start the processor running at the specified address An error is returned if an unrecoverable error is encountered Typically this would be an undefined opcode, or an error returned from a breakpointer handler

func (*Processor) SetBreakpoint

func (p *Processor) SetBreakpoint(breakAt uint16, handler BreakpointHandler) *Processor

SetBreakpoint is used to set a breakpoint consisting of a user provided handler The handler must return it's desired breakpoint address and a function that will be invoked when the PC reaches the breakpoint (before the instruction is executed) Call only when the processor is stopped Multiple breakpointers/handlers can be set at a given address and will be executed in the order set

func (*Processor) SetClock

func (p *Processor) SetClock(cyclesPerSecond int64) *Processor

SetClock will set the clock speed in processor cycles per second I.E. for a 1MHZ clock set ticksPerSecond to 1,000,000 A value of zero is unrestricted (all instructions run at maximum possible speed with no regard for timing)

func (*Processor) SetDebugWriter

func (p *Processor) SetDebugWriter(w io.Writer) *Processor

SetDebugWriter can be used to set a writer to which debug messages will be sent when debug options are activated This defaults to STDERR

func (*Processor) SetModel65C02

func (p *Processor) SetModel65C02() *Processor

SetModel65C02 will load 65C02 additional opcodes and set other specific behaviors for that processor type

func (*Processor) SetOption

func (p *Processor) SetOption(opt ProcessorOption, value bool) *Processor

SetOption can be used to set one of several processor options these are generally set to true to enable debugging facilities

func (*Processor) SetVector

func (p *Processor) SetVector(vector uint16, value uint16) *Processor

SetVector can be used to set one of the system vectors. The value of vector should be one of:

func (*Processor) Step

func (p *Processor) Step() (err error, stop bool)

Step executes a single instruction, returning any error that may occur which is typically an undefined opcode or errors resulting from breakpointer handlers

func (*Processor) Stop

func (p *Processor) Stop()

Stop will stop the processor if running

type ProcessorModel

type ProcessorModel int

ProcessorModel allows for different processor models and their associated behaviors the default model is 6502

const (
	// ProcessorModel6502 represents the original 6502
	ProcessorModel6502 ProcessorModel = iota

	// ProcessorModel65C02 represents the CMOS 65C02
	// which exhibits some different behaviors with respect to the decimal flag
	// on BRK and interrupt
	ProcessorModel65C02
)

type ProcessorOption

type ProcessorOption int

ProcessorOption defines options that can be used to influence the behavior of the processor Hint: setting some of these options via breakpoint handlers can be useful for debugging

const (
	// ErrorOnSelfJump option, when activated, will cause an error to be generated by the processor
	// if a branch or JMP instruction redirects back to itself
	// This is useful for testing scenarios
	ErrorOnSelfJump ProcessorOption = iota

	// Trace option will cause output of a single line of debug for every instructions (pre-execution)
	Trace

	// TraceStack option will cause the stack to be dumped prior to every operation
	TraceStack

	// TraceInterrupts will cause messages to be printed when external interrupts are triggered
	TraceInterrupts

	// ErrorOnJAM will cause an error to be generated if an (illegal) JAM is enconutered
	// with the illegal instruction set enabled
	// if this is not set, then the processor will just lock up
	ErrorOnJAM

	// AutoResetIRQ will cause the IRQ line to be forcefully unasserted when the IRQ
	// branch is taken
	AutoResetIRQ

	// AutoRsetNMI will cause the NMI line to be forcefully unasserted when the NMI
	// branch is taken
	AutoResetNMI

	// Fix6502BrokenJMP will fix the incorrect behavior of indirect JUMP on 6502 (not 65C02 which is not broken)
	// The (implemented) broken behavior is to jump to the address stored at xxff (L), xx00 (H) instead of
	// xxff (L), xx+100 (H)
	Fix6052BrokenJMP
)

type ProcessorPerformance

type ProcessorPerformance struct {
	// RanForNanoseconds indicates the number of nanoseconds for which the processor last ran
	RanForNanoseconds int64

	// RanForCycles indicates the number of cycles for which the processor last ran
	RanForCycles int64

	// EffectiveClock indicates the achieved clock rate of the last ran, in processor cycles per second
	EffectiveClock int64

	// InstructionsExecuted is the count of instructions executed
	InstructionsExecuted uint64
}

ProcessorPerformance is used to report on the performance of the processor The data contained within is not valid if the processor is running, it is only valid once the processor has been stopped and reflects the stats from the last run

type ProgramCounter

type ProgramCounter struct {
	// contains filtered or unexported fields
}

func (*ProgramCounter) Current

func (pc *ProgramCounter) Current() uint16

func (*ProgramCounter) Init

func (pc *ProgramCounter) Init(p *Processor)

func (*ProgramCounter) Next

func (pc *ProgramCounter) Next() uint8

func (*ProgramCounter) Set

func (pc *ProgramCounter) Set(val uint16)

type RawMemory

type RawMemory struct {
	// contains filtered or unexported fields
}

RawMemory implements a simple R/W 64K address space with no special features

func (*RawMemory) Clear

func (m *RawMemory) Clear()

Clear clears all memory

func (*RawMemory) DisableReadDebugging

func (m *RawMemory) DisableReadDebugging()

DisableReadDebugging will disable debugging of reads

func (*RawMemory) DisableWriteDebugging

func (m *RawMemory) DisableWriteDebugging()

DisableWriteDebugging will disable debugging of writes

func (*RawMemory) EnableReadDebugging

func (m *RawMemory) EnableReadDebugging(w io.Writer)

EnableReadDebugging will report every read to the provided writer

func (*RawMemory) EnableWriteDebugging

func (m *RawMemory) EnableWriteDebugging(w io.Writer)

EnableWriteDebugging will report every write to the provided writer

func (*RawMemory) Read

func (m *RawMemory) Read(location uint16) uint8

Read a memory location

func (*RawMemory) Write

func (m *RawMemory) Write(location uint16, value uint8)

Write a memory location

type Registers

type Registers struct {
	// A is the accumulator
	A uint8

	// X is the X register
	X uint8

	// Y is the Y register
	Y uint8

	// SR is the status register
	SR StatusRegister

	// SP is the stack pointer
	SP StackPointer

	// PC is the program counter
	PC ProgramCounter
}

Registers defines the structure containing all processor registers

type SEC

type SEC struct{}

func (*SEC) Exec

func (i *SEC) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*SEC) Mnemonic

func (i *SEC) Mnemonic() string

type SED

type SED struct{}

func (*SED) Exec

func (i *SED) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*SED) Mnemonic

func (i *SED) Mnemonic() string

type SEI

type SEI struct{}

func (*SEI) Exec

func (i *SEI) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*SEI) Mnemonic

func (i *SEI) Mnemonic() string

type SRFlag

type SRFlag uint8
const (
	// SRFlagN is the bit address of the negative flag
	SRFlagN SRFlag = 7

	// SRFlagV is the bit address of the overflow flag
	SRFlagV SRFlag = 6

	// SRFlagU is the bit address of the unused flag
	SRFlagU SRFlag = 5

	// SRFlagB is the bit address of the break flag
	SRFlagB SRFlag = 4

	// SRFlagD is the bit addres of the decimal (BCD) flag
	SRFlagD SRFlag = 3

	// SRFlagI is the bit address of the interrupt flag
	SRFlagI SRFlag = 2

	// SRFlagZ is the bit address of the zero flag
	SRFlagZ SRFlag = 1

	// SRFlagC is the bit address of the carry flag
	SRFlagC SRFlag = 0
)

type STX

type STX struct{}

func (*STX) Exec

func (i *STX) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*STX) Mnemonic

func (i *STX) Mnemonic() string

type STY

type STY struct{}

func (*STY) Exec

func (i *STY) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*STY) Mnemonic

func (i *STY) Mnemonic() string

type StackPointer

type StackPointer struct {
	// contains filtered or unexported fields
}

StackPointer is our implementation of the stack pointer

func (*StackPointer) GetStackPointer

func (sp *StackPointer) GetStackPointer() uint8

GetStackPointer retrieves the current stack pointer value

func (*StackPointer) PeekStackHead

func (sp *StackPointer) PeekStackHead() uint8

PeekStackHead returns the byte on the stack head without altering the stack

func (*StackPointer) Pop

func (sp *StackPointer) Pop() uint8

Pop pops a byte off the stack

func (*StackPointer) Push

func (sp *StackPointer) Push(value uint8)

Push pushes a byte to the stack

func (*StackPointer) SetStackPointer

func (sp *StackPointer) SetStackPointer(ptr uint8)

SetStackPointer is used to explicitly set the stack pointer

func (*StackPointer) String

func (sp *StackPointer) String() string

String provides a string dump of the stack

type StatusRegister

type StatusRegister struct {
	// contains filtered or unexported fields
}

StatusRegister defines a status register entity

func (*StatusRegister) Clear

func (s *StatusRegister) Clear(flag SRFlag)

Clear will clear a specific flag in the status register

func (*StatusRegister) IsSet

func (s *StatusRegister) IsSet(flag SRFlag) bool

IsSet returns true if the specified flag is set, otherwise false

func (*StatusRegister) Set

func (s *StatusRegister) Set(flag SRFlag)

Set will set a specific flag in the status register

func (*StatusRegister) SetTo

func (s *StatusRegister) SetTo(flag SRFlag, state bool)

SetTo will set a specific flag in the status register to either on or off depending on the provided state (true=on)

func (*StatusRegister) String

func (s *StatusRegister) String() string

String provides a string representation of the status register current state

func (*StatusRegister) Value

func (s *StatusRegister) Value() uint8

Value returns the raw value of the status register

type SystemVector

type SystemVector uint16

SystemVector type is used for all available system vector addresses

const (
	// VectorNMI is the non maskable interrupt vector address
	VectorNMI SystemVector = 0xFFFA

	// VectorReset is the reset vector address
	VectorReset SystemVector = 0xFFFC

	// VectorIRQ is the interrupt vector request
	VectorIRQ SystemVector = 0xFFFE
)

type TAX

type TAX struct{}

func (*TAX) Exec

func (i *TAX) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*TAX) Mnemonic

func (i *TAX) Mnemonic() string

type TAY

type TAY struct{}

func (*TAY) Exec

func (i *TAY) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*TAY) Mnemonic

func (i *TAY) Mnemonic() string

type TSX

type TSX struct{}

func (*TSX) Exec

func (i *TSX) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*TSX) Mnemonic

func (i *TSX) Mnemonic() string

type TXA

type TXA struct{}

func (*TXA) Exec

func (i *TXA) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*TXA) Mnemonic

func (i *TXA) Mnemonic() string

type TXS

type TXS struct{}

func (*TXS) Exec

func (i *TXS) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*TXS) Mnemonic

func (i *TXS) Mnemonic() string

type TYA

type TYA struct{}

func (*TYA) Exec

func (i *TYA) Exec(proc *Processor, mode AddressingMode, data uint8, data16 uint16) error

func (*TYA) Mnemonic

func (i *TYA) Mnemonic() string

Source Files

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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