struct CPU

Overview

The core CPU that will have the methods and IV's necessary to emulate the 6502 microprocessor

Defined in:

Constructors

Instance Method Summary

Constructor Detail

def self.new(debug : Bool) #

Instance Method Detail

def advance_next_ins #

This is the same as next_ins except it decrements the cycles_remaining.


def cycles_remaining : Int32 #

The cycles remaining for the execution of an instruction. Some instructions take more cycles than others, so after the first byte is fetched from memory using next_ins, then there is 1 less cycle remaining for that instruction. Example: LDX_IMM has 2 cycles, but after the first call to next_ins drops that down to 1, so when it's being processed, this will be set to 1


def cycles_remaining=(cycles_remaining) #

The cycles remaining for the execution of an instruction. Some instructions take more cycles than others, so after the first byte is fetched from memory using next_ins, then there is 1 less cycle remaining for that instruction. Example: LDX_IMM has 2 cycles, but after the first call to next_ins drops that down to 1, so when it's being processed, this will be set to 1


def display_cpu_state(ins : UInt8) #

This will display the state of the CPU


def display_debug_prompt : Bool #

This will return true when it's okay to advance the cpu, but false otherwise This will only be called when @debug is true (can be toggled by passing -d at command line) This will display a prompt with two commands: dump stack and dump memory [start] [end]

dump stack This command will dump the stack to STDOUT

*dump memory [start] [end] This command will take a start and end addresses and dump their contents to STDOUT


def execute #

This will execute the loaded program by taking the first byte and decoding it as an instruction, and continuing to decode instructions until the next byte read is 0. If it fails to decode it, it will print an error.


def get_processor_status_string #

def load_program(program : Array(UInt8)) #

Loads a program into memory at address 0x0200


def memory : Memory #

The memory of the cpu


def next_ins #

Get the next instruction in memory without affecting the cycles remaining. This is mostly used for getting the first byte in an instruction, which would count as the first cycle of an instruction. This will increment the program counter


def processor_status : BitArray #

The processor status holds bits specific to certain statuses of the processor

The bits are as follows:

  0 : Carry flag
  1 : Zero flag
  2 : Interrupt disable
  3 : Decimal mode
  4 : Break command
  5 : Overflow flag
  6 : Negative flag

def program_counter : UInt16 #

The program counter, which is used to indicate the next instruction to load from the program in memory. This can be changed by using jump instructions, calling a subroutine, or exiting a subrouting or by an interrupt


def program_counter=(program_counter : UInt16) #

The program counter, which is used to indicate the next instruction to load from the program in memory. This can be changed by using jump instructions, calling a subroutine, or exiting a subrouting or by an interrupt


def reg_a : UInt8 #

Accumulator register


def reg_a=(reg_a : UInt8) #

Accumulator register


def reg_x : UInt8 #

X register


def reg_x=(reg_x : UInt8) #

X register


def reg_y : UInt8 #

Y register


def reg_y=(reg_y : UInt8) #

Y register


def stack_pointer : UInt8 #

The pointer to the next place on the stack to be pushed. This starts at the top and moves downwards, starting at 0x01FF and ending at 0x0100. This is an 8-bit register which holds the low 8 bits of the next location on the stack to be pushed to When the stack is pushed, this decrements, when the stack is popped, it is incremented This register does not handle overflows so overflows will have to be handled manually


def stack_pointer=(stack_pointer : UInt8) #

The pointer to the next place on the stack to be pushed. This starts at the top and moves downwards, starting at 0x01FF and ending at 0x0100. This is an 8-bit register which holds the low 8 bits of the next location on the stack to be pushed to When the stack is pushed, this decrements, when the stack is popped, it is incremented This register does not handle overflows so overflows will have to be handled manually


def stack_pop #

Pop a byte off the stack

This will increment the stack pointer and decrement the cycles remaining This will take up one cycle to complete

This returns the value popped from the stack at stack_pointer + 1


def stack_push(value : UInt8) #

Push a byte onto the stack portion of memory. See Memory::data for more info on where the stack is in memory. This counts as a cycle so when using this, make sure you have enough cycles set Todo: Add assertion for cycles_remaining


def stack_push(value : UInt16) #

Push a word onto the stack. Because 6502 is in little endian, it will take the low byte then the high byte in that order on the stack