cpu

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2020 License: GPL-3.0, GPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package cpu emulates the 6507 microprocessor found in the Atari VCS. Like all 8-bit processors of the era, the 6507 executes instructions according to the single byte value read from an address pointed to by the program counter. This single byte is the opcode and is looked up in the instruction table. The instruction definition for that opcode is then used to move execution of the program forward.

The instance of the CPU type require an instance of a bus.CPUBus implementation as the sole argument. The CPUBus interface defines the memory operations required by the CPU. See the bus package for details.

The bread-and-butter of the CPU type is the ExecuteInstruction() function. Its sole argument is a callback function to be called at every cycle boundry of the instruction.

Let's assume mem is an instance of the CPUBus interface loaded 6507 instructions.

mc, _ := cpu.NewCPU(mem)

numCycles := 0
numInstructions := 0

for {
	mc.ExecuteInstruction(func() error {
		numCycles ++
	})
	numInstructions ++
}

The above program does nothing interesting except to show how ExecuteInstruction() can be used to pump information to an callback function. The VCS emulation uses this to run the TIA emulation three times for every CPU cycle - the CPU clock runs at 1.19MHz while the TIA clock runs at 3.57Mhz. TIA emulation is discussed more fully in the TIA package.

The CPU type contains some public fields that are worthy of mention. The LastResult field can be probed for information about the last instruction executed, or about the current instruction being executed if accessed from ExecuteInstruction()'s callback function. See the result package for more information. Very useful for debuggers.

The NoFlowControl flag is used by the disassembly package to prevent the CPU from honouring "flow control" functions (ie. JMP, BNE, BEQ, etc.). See instructions package for classifications.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CPU

type CPU struct {
	PC     *registers.ProgramCounter
	A      *registers.Register
	X      *registers.Register
	Y      *registers.Register
	SP     *registers.Register
	Status *registers.StatusRegister

	// controls whether cpu executes a cycle when it receives a clock tick (pin
	// 3 of the 6507)
	RdyFlg bool

	// last result. the address field is guaranteed to be always valid except
	// when the CPU has just been reset. we use this fact to help us decide
	// whether the CPU has just been reset (see HasReset() function)
	LastResult execution.Result

	// NoFlowControl sets whether the cpu responds accurately to instructions
	// that affect the flow of the program (branches, JPS, subroutines and
	// interrupts).  we use this in the disassembly package to make sure we
	// reach every part of the program.
	//
	// note that the alteration of flow as a result of bank switching is still
	// possible even if NoFlowControl is true. this is because bank switching
	// is outside of the direct control of the CPU.
	NoFlowControl bool

	// Interrupted indicated that the CPU has been put into a state outside of
	// its normal operation. When true work may be done on the CPU that would
	// otherwise be considered an error. Resets to false on every call to
	// ExecuteInstruction()
	Interrupted bool
	// contains filtered or unexported fields
}

CPU implements the 6507 found as found in the Atari 2600. Register logic is implemented by the Register type in the registers sub-package.

func NewCPU

func NewCPU(mem bus.CPUBus) (*CPU, error)

NewCPU is the preferred method of initialisation for the CPU structure. Note that the CPU will be initialised in a random state.

func (*CPU) ExecuteInstruction

func (mc *CPU) ExecuteInstruction(cycleCallback func() error) error

ExecuteInstruction steps CPU forward one instruction. The basic process when executing an instruction is this:

  1. read opcode and look up instruction definition
  2. read operands (if any) according to the addressing mode of the instruction
  3. using the mnemonic as a guide, perform the instruction on the data

All instructions take at least 2 cycle. After each cycle, the cycleCallback() function is run, thereby allowing the rest of the VCS hardware to operate.

func (CPU) HasReset

func (mc CPU) HasReset() bool

HasReset checks whether the CPU has recently been reset

func (*CPU) LoadPC

func (mc *CPU) LoadPC(directAddress uint16) error

LoadPC loads the contents of directAddress into the PC

func (*CPU) LoadPCIndirect

func (mc *CPU) LoadPCIndirect(indirectAddress uint16) error

LoadPCIndirect loads the contents of indirectAddress into the PC

func (*CPU) Reset

func (mc *CPU) Reset(randomState bool) error

Reset reinitialises all registers

func (*CPU) String

func (mc *CPU) String() string

Directories

Path Synopsis
Package execution tracks the result of instruction execution on the CPU.
Package execution tracks the result of instruction execution on the CPU.
Package instructions defines the table of instruction for the 6507.
Package instructions defines the table of instruction for the 6507.
Package registers implements the three types of registers found in the 6507.
Package registers implements the three types of registers found in the 6507.
test
Package test contains functions useful for testing CPU registers.
Package test contains functions useful for testing CPU registers.

Jump to

Keyboard shortcuts

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