1
0
mirror of https://github.com/ariejan/i6502.git synced 2024-10-31 23:09:44 +00:00
i6502/cpu_test.go
Ariejan de Vroom da43c2bca1 Update Memory interface
Because io.Reader and io.Writer already claim the functions Read and
Write it was necessary to rename the Memory interface methods Read and
Write to ReadByte and WriteByte.
2014-08-19 16:49:48 +02:00

3261 lines
65 KiB
Go

package i6502
import (
"fmt"
"io/ioutil"
"testing"
"github.com/stretchr/testify/assert"
)
// Creates a new machine, returning the different parts
func NewRamMachine() (*Cpu, *AddressBus, *Ram) {
ram, _ := NewRam(0x100000) // Full 64kB
bus, _ := NewAddressBus()
bus.Attach(ram, 0x0000)
cpu, _ := NewCpu(bus)
cpu.Reset()
return cpu, bus, ram
}
func loadProgram(path string) []byte {
data, err := ioutil.ReadFile(path)
if err != nil {
panic(fmt.Sprintf("Cannot open program file '%s'\n.", path))
}
return data
}
func TestNewCpu(t *testing.T) {
cpu, err := NewCpu(nil)
assert.NotNil(t, cpu)
assert.Nil(t, err)
}
func TestStackPushPopPeek(t *testing.T) {
assert := assert.New(t)
cpu, _, _ := NewRamMachine()
assert.Equal(0xFF, cpu.SP)
cpu.stackPush(0x42)
cpu.stackPush(0xA0)
assert.Equal(0xFD, cpu.SP)
assert.Equal(0x42, cpu.Bus.ReadByte(0x1FF))
assert.Equal(0xA0, cpu.Bus.ReadByte(0x1FE))
peekValue := cpu.stackPeek()
assert.Equal(0xFD, cpu.SP)
assert.Equal(0xA0, peekValue)
popValue := cpu.stackPop()
assert.Equal(0xFE, cpu.SP)
assert.Equal(0xA0, popValue)
}
func TestCpuAddressBus(t *testing.T) {
assert := assert.New(t)
cpu, bus, _ := NewRamMachine()
assert.Equal(cpu.Bus, bus)
assert.NotNil(cpu.Bus)
}
func TestCpuReset(t *testing.T) {
assert := assert.New(t)
cpu, _, _ := NewRamMachine()
cpu.Bus.Write16(0xFFFC, 0x1234)
cpu.Reset()
// **1101** is specified, but we are satisfied with
// 00110100 here.
assert.Equal(0x34, cpu.P)
assert.True(cpu.getIrqDisable())
assert.False(cpu.getDecimal())
assert.True(cpu.getBreak())
// Read PC from $FFFC-FFFD
assert.Equal(0x1234, cpu.PC)
}
func TestCpuInterrupt(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.Bus.Write16(0xFFFE, 0x1234) // Write the IRQ vector
cpu.setIrqDisable(false) // Enable interrupts
cpu.SP = 0xFF // Set the stack pointer
cpu.PC = 0x0380 // Some fake point of execution
assert.Equal(t, 0xFF, cpu.SP)
status := cpu.P
// Trigger IRQ
cpu.Interrupt()
assert.Equal(t, 0x1234, cpu.PC)
assert.Equal(t, 0x03, cpu.Bus.ReadByte(0x01FF))
assert.Equal(t, 0x80, cpu.Bus.ReadByte(0x01FE))
assert.Equal(t, status, cpu.Bus.ReadByte(0x01FD))
assert.True(t, cpu.getIrqDisable())
}
func TestProgramLoading(t *testing.T) {
assert := assert.New(t)
program := []byte{0xEA, 0xEB, 0xEC}
cpu, bus, _ := NewRamMachine()
cpu.LoadProgram(program, 0x0300)
assert.Equal(0xEA, bus.ReadByte(0x0300))
assert.Equal(0xEB, bus.ReadByte(0x0301))
assert.Equal(0xEC, bus.ReadByte(0x0302))
assert.Equal(0x0300, cpu.PC)
}
//// NOP
func TestNOP(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xEA}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
}
func TestSEC(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x38}, 0x0300)
assert.False(t, cpu.getCarry())
cpu.Step()
assert.True(t, cpu.getCarry())
}
func TestSED(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xF8}, 0x0300)
assert.False(t, cpu.getDecimal())
cpu.Step()
assert.True(t, cpu.getDecimal())
}
func TestSEI(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x78}, 0x0300)
cpu.setIrqDisable(false)
assert.False(t, cpu.getIrqDisable())
cpu.Step()
assert.True(t, cpu.getIrqDisable())
}
func TestCLC(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x18}, 0x0300)
cpu.setCarry(true)
assert.True(t, cpu.getCarry())
cpu.Step()
assert.False(t, cpu.getCarry())
}
func TestCLD(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xD8}, 0x0300)
cpu.setDecimal(true)
assert.True(t, cpu.getDecimal())
cpu.Step()
assert.False(t, cpu.getDecimal())
}
func TestCLI(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x58}, 0x0300)
cpu.setIrqDisable(true)
assert.True(t, cpu.getIrqDisable())
cpu.Step()
assert.False(t, cpu.getIrqDisable())
}
func TestCLV(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xB8}, 0x0300)
cpu.setOverflow(true)
assert.True(t, cpu.getOverflow())
cpu.Step()
assert.False(t, cpu.getOverflow())
}
//// ADC
func TestADCImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0x53}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x95, cpu.A)
assert.False(t, cpu.getCarry())
}
func TestADCWithCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0x53}, 0x0300)
cpu.A = 0xC0
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x13, cpu.A)
assert.True(t, cpu.getCarry())
}
func TestADCWithCarryOver(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0x04}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x05
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x0A, cpu.A)
assert.False(t, cpu.getCarry())
}
func TestADCWithOverflow(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0xD0}, 0x0300)
cpu.A = 0x90
// 0x90 + 0xD0 = 0x160
// 208 + 144 = 352 => unsigned carry
// -48 + -112 = 96 => signed overflow
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x60, cpu.A)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getOverflow())
}
func TestADCZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0x00}, 0x0300)
cpu.A = 0x00
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestADCNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0xF7}, 0x0300)
cpu.A = 0x00
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF7, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestADCDecimal(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x69, 0x28}, 0x0300)
cpu.setDecimal(true)
cpu.A = 0x19
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x47, cpu.A)
}
func TestADCZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x65, 0x53}, 0x0300)
cpu.A = 0x42
cpu.Bus.WriteByte(0x53, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
func TestADCZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x75, 0x53}, 0x0300)
cpu.A = 0x42
cpu.X = 0x01
cpu.Bus.WriteByte(0x54, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
func TestADCAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x6D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Bus.WriteByte(0x8000, 0x12)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
func TestADCAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x7D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x12)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
func TestADCAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x79, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.WriteByte(0x8002, 0x12)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
func TestADCIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x61, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.Write16(0x82, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
func TestADCIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x71, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.Write16(0x80, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
}
//// SBC
func TestSBCImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE9, 0x01}, 0x0300)
cpu.A = 0x42
cpu.setCarry(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x41, cpu.A)
assert.True(t, cpu.getCarry())
}
func TestSBCWithoutCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE9, 0x01}, 0x0300)
cpu.A = 0x42
cpu.setCarry(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x40, cpu.A)
assert.True(t, cpu.getCarry())
}
func TestSBCNegativeNoCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE9, 0x43}, 0x0300)
cpu.A = 0x42
cpu.setCarry(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xff, cpu.A)
assert.False(t, cpu.getCarry())
assert.True(t, cpu.getNegative())
}
func TestSBCDecimal(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE9, 0x03}, 0x0300)
cpu.setDecimal(true)
cpu.A = 0x32
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x28, cpu.A)
}
func TestSBCZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE9, 0x42}, 0x0300)
cpu.A = 0x42
cpu.setCarry(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestSBCZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE5, 0x53}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.Bus.WriteByte(0x53, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
func TestZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xF5, 0x53}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.X = 0x01
cpu.Bus.WriteByte(0x54, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
func TestSBCAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xED, 0x00, 0x80}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.Bus.WriteByte(0x8000, 0x12)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
func TestSBCAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xFD, 0x00, 0x80}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x12)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
func TestSBCAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xF9, 0x00, 0x80}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.WriteByte(0x8002, 0x12)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
func TestSBCIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE1, 0x80}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.Write16(0x82, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
func TestSBCIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xF1, 0x80}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.Write16(0x80, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x12)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x30, cpu.A)
}
//// INX
func TestINX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE8}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x43, cpu.X)
}
func TestINXRollover(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE8}, 0x0300)
cpu.X = 0xFF
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.X)
}
//// INY
func TestINY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xC8}, 0x0300)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x43, cpu.Y)
}
func TestINYRollover(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xC8}, 0x0300)
cpu.Y = 0xFF
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.Y)
}
//// INC
func TestINCZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xE6, 0x42}, 0x0300)
cpu.Bus.WriteByte(0x42, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x42))
}
func TestINCZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xF6, 0x42}, 0x0300)
cpu.X = 0x01
cpu.Bus.WriteByte(0x43, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x43))
}
func TestINCAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xEE, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8000))
}
func TestINCAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xFE, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8002))
}
//// DEX
func TestDEX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xCA}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x41, cpu.X)
}
func TestDEXRollover(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xCA}, 0x0300)
cpu.X = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xFF, cpu.X)
}
//// DEY
func TestDEY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x88}, 0x0300)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x41, cpu.Y)
}
func TestDEYRollover(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x88}, 0x0300)
cpu.Y = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xFF, cpu.Y)
}
//// DEC
func TestDECZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xC6, 0x42}, 0x0300)
cpu.Bus.WriteByte(0x42, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x42))
}
func TestDECZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xD6, 0x42}, 0x0300)
cpu.X = 0x01
cpu.Bus.WriteByte(0x43, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x43))
}
func TestDECAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xCE, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x8000))
}
func TestDECAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xDE, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x8002))
}
//// LDA
func TestLDAImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA9, 0x42}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.A)
}
func TestLDANegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA9, 0xAE}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xAE, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestLDAZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA9, 0x00}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestLDAZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA5, 0x42}, 0x0300)
cpu.Bus.WriteByte(0x42, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
func TestLDAZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xB5, 0x41}, 0x0300)
cpu.X = 0x01
cpu.Bus.WriteByte(0x42, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
func TestLDAAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xAD, 0x00, 0x80}, 0x0300)
cpu.Bus.Write16(0x8000, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
func TestLDAAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xBD, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.Write16(0x8002, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
func TestLDAAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xB9, 0x00, 0x80}, 0x0300)
cpu.Y = 0x02
cpu.Bus.Write16(0x8002, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
func TestLDAIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA1, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.Write16(0x82, 0xC000)
cpu.Bus.WriteByte(0xC000, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
func TestLDAIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xB1, 0x80}, 0x0300)
cpu.Y = 0x02
cpu.Bus.Write16(0x80, 0xC000)
cpu.Bus.WriteByte(0xC002, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.A)
}
//// LDX
func TestLDXImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA2, 0x42}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.X)
}
func TestLDXNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA2, 0xAE}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xAE, cpu.X)
assert.True(t, cpu.getNegative())
}
func TestLDXZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA2, 0x00}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.X)
assert.True(t, cpu.getZero())
}
func TestLDXZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA6, 0x42}, 0x0300)
cpu.Bus.WriteByte(0x42, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.X)
}
func TestLDXZeropageY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xB6, 0x41}, 0x0300)
cpu.Y = 0x01
cpu.Bus.WriteByte(0x42, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.X)
}
func TestLDXAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xAE, 0x00, 0x80}, 0x0300)
cpu.Bus.Write16(0x8000, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.X)
}
func TestLDXAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xBE, 0x00, 0x80}, 0x0300)
cpu.Y = 0x02
cpu.Bus.Write16(0x8002, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.X)
}
//// LDY
func TestLDYImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA0, 0x42}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Y)
}
func TestLDYNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA0, 0xAE}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xAE, cpu.Y)
assert.True(t, cpu.getNegative())
}
func TestLDYZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA0, 0x00}, 0x0300)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.Y)
assert.True(t, cpu.getZero())
}
func TestLDYZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA4, 0x42}, 0x0300)
cpu.Bus.WriteByte(0x42, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.Y)
}
func TestLDYZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xB4, 0x41}, 0x0300)
cpu.X = 0x01
cpu.Bus.WriteByte(0x42, 0xF8)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF8, cpu.Y)
}
func TestLDYAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xAC, 0x00, 0x80}, 0x0300)
cpu.Bus.Write16(0x8000, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.Y)
}
func TestLDYAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xBC, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.Write16(0x8002, 0xF8)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF8, cpu.Y)
}
//// ORA
func TestORAImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x09, 0x02}, 0x0300)
cpu.A = 0x70
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x72, cpu.A)
}
func TestORANegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x09, 0x02}, 0x0300)
cpu.A = 0xF0
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestORAZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x09, 0x00}, 0x0300)
cpu.A = 0x00
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestORAZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x05, 0x42}, 0x0300)
cpu.A = 0xF0
cpu.Bus.WriteByte(0x0042, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
func TestORAZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x15, 0x40}, 0x0300)
cpu.A = 0xF0
cpu.X = 0x02
cpu.Bus.WriteByte(0x0042, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
func TestORAAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x0D, 0x00, 0x80}, 0x0300)
cpu.A = 0xF0
cpu.Bus.WriteByte(0x8000, 0x02)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
func TestORAAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x1D, 0x00, 0x80}, 0x0300)
cpu.A = 0xF0
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x02)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
func TestORAAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x19, 0x00, 0x80}, 0x0300)
cpu.A = 0xF0
cpu.Y = 0x02
cpu.Bus.WriteByte(0x8002, 0x02)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
func TestORAIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x01, 0x40}, 0x0300)
cpu.A = 0xF0
cpu.X = 0x02
cpu.Bus.Write16(0x42, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
func TestORAIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x11, 0x40}, 0x0300)
cpu.A = 0xF0
cpu.Y = 0x02
cpu.Bus.Write16(0x40, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xF2, cpu.A)
}
//// AND
func TestANDImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x29, 0x0f}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestANDNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x29, 0xF0}, 0x0300)
cpu.A = 0xA3
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xA0, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestANDZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x29, 0xf0}, 0x0300)
cpu.A = 0x0f
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestANDZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x25, 0x42}, 0x0300)
cpu.A = 0xE9
cpu.Bus.WriteByte(0x0042, 0x0f)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x09, cpu.A)
}
func TestANDZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x35, 0x40}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.WriteByte(0x0042, 0x0F)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestANDAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x2D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Bus.WriteByte(0x8000, 0x0F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestANDAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x3D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x0F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestANDAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x39, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.WriteByte(0x8002, 0x0F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestANDIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x21, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.Write16(0x82, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x0F)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestANDIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x31, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.Write16(0x80, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x0F)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
//// EOR
func TestEORImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x49, 0x7f}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x49, 0xf7}, 0x0300)
cpu.A = 0x24
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xD3, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestEORZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x49, 0xff}, 0x0300)
cpu.A = 0xff
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestEORZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x45, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Bus.WriteByte(0x0080, 0x7f)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x55, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.WriteByte(0x0082, 0x7F)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x4D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Bus.WriteByte(0x8000, 0x7F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x5D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x7F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x59, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.WriteByte(0x8002, 0x7F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x41, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.Write16(0x82, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x7F)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
func TestEORIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x51, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.Write16(0x80, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x7F)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x3D, cpu.A)
}
//// STA
func TestSTAZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x85, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x0080))
}
func TestSTAZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x95, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x0082))
}
func TestSTAAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x8D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x8000))
}
func TestSTAAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x9D, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x8002))
}
func TestSTAAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x99, 0x00, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.WriteByte(0x8002, 0x7F)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x8002))
}
func TestSTAIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x81, 0x80}, 0x0300)
cpu.A = 0x42
cpu.X = 0x02
cpu.Bus.Write16(0x82, 0xC000)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0xC000))
}
func TestSTAIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x91, 0x80}, 0x0300)
cpu.A = 0x42
cpu.Y = 0x02
cpu.Bus.Write16(0x80, 0xC000)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0xC002))
}
//// STX
func TestSTXZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x86, 0x80}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x0080))
}
func TestSTXZeropageY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x96, 0x80}, 0x0300)
cpu.X = 0x42
cpu.Y = 0x02
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x0082))
}
func TestSTXAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x8E, 0x00, 0x80}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x8000))
}
//// STY
func TestSTYZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x84, 0x80}, 0x0300)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x0080))
}
func TestSTYZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x94, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x0082))
}
func TestSTYAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x8C, 0x00, 0x80}, 0x0300)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x42, cpu.Bus.ReadByte(0x8000))
}
//// TAX
func TestTAX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xAA}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x42, cpu.X)
}
func TestTAXNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xAA}, 0x0300)
cpu.A = 0xE0
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xE0, cpu.X)
assert.True(t, cpu.getNegative())
}
func TestTAXZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xAA}, 0x0300)
cpu.A = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.X)
assert.True(t, cpu.getZero())
}
//// TAY
func TestTAY(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA8}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x42, cpu.Y)
}
func TestTAYNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA8}, 0x0300)
cpu.A = 0xE0
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xE0, cpu.Y)
assert.True(t, cpu.getNegative())
}
func TestTAYZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xA8}, 0x0300)
cpu.A = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.Y)
assert.True(t, cpu.getZero())
}
//// TXA
func TestTXA(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x8A}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x42, cpu.A)
}
func TestTXANegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x8A}, 0x0300)
cpu.X = 0xE0
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xE0, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestTXAZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x8A}, 0x0300)
cpu.X = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
//// TYA
func TestTYA(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x98}, 0x0300)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x42, cpu.A)
}
func TestTYANegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x98}, 0x0300)
cpu.Y = 0xE0
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xE0, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestTYAZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x98}, 0x0300)
cpu.Y = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
//// TSX
func TestTSX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xBA}, 0x0300)
cpu.SP = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x42, cpu.X)
}
func TestTSXNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xBA}, 0x0300)
cpu.SP = 0xE0
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xE0, cpu.X)
assert.True(t, cpu.getNegative())
}
func TestTSXZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0xBA}, 0x0300)
cpu.SP = 0x00
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.X)
assert.True(t, cpu.getZero())
}
//// TXS
func TestTXS(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x9A}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x42, cpu.SP)
}
//// ASL
func TestASLaccumulator(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x0A}, 0x0300)
cpu.A = 0x01
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestASLAccumulatorNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x0A}, 0x0300)
cpu.A = 0x40 // 0100 0000
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x80, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestASLAccumulatorZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x0A}, 0x0300)
cpu.A = 0x80 // 1000 0000
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestASLAccumulatorCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x0A}, 0x0300)
cpu.A = 0xAA // 1010 1010
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x54, cpu.A)
assert.True(t, cpu.getCarry())
}
func TestASLzeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x06, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x0080))
}
func TestASLzeropageNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x06, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x40)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x80, cpu.Bus.ReadByte(0x0080))
assert.True(t, cpu.getNegative())
}
func TestASLzeropageZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x06, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x80)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x0080))
assert.True(t, cpu.getZero())
}
func TestASLzeropageCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x06, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0xAA)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x54, cpu.Bus.ReadByte(0x0080))
assert.True(t, cpu.getCarry())
}
func TestASLzeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x16, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x0082, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x0082))
}
func TestASLabsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x0E, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8000))
}
func TestASLabsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x1E, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8002))
}
//// LSR
func TestLSRaccumulator(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x4A}, 0x0300)
cpu.A = 0x02
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x01, cpu.A)
}
func TestLSRAccumulatorZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x4A}, 0x0300)
cpu.A = 0x01
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
func TestLSRAccumulatorCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x4A}, 0x0300)
cpu.A = 0x01
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getCarry())
}
func TestLSRzeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x46, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x01, cpu.Bus.ReadByte(0x0080))
}
func TestLSRzeropageZero(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x46, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x0080))
assert.True(t, cpu.getZero())
}
func TestLSRzeropageCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x46, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x00, cpu.Bus.ReadByte(0x0080))
assert.True(t, cpu.getCarry())
}
func TestLSRzeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x56, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x0082, 0x04)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x0082))
}
func TestLSRabsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x4E, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x04)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8000))
}
func TestLSRabsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x5E, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x04)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8002))
}
//// ROL
func TestROLAccumulator(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x2A}, 0x0300)
cpu.A = 0x01
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x02, cpu.A)
}
func TestROLAccumulatorZeroAndCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x2A}, 0x0300)
cpu.setCarry(false)
cpu.A = 0x80
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
assert.True(t, cpu.getCarry())
}
func TestROLAccumulatorNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x2A}, 0x0300)
cpu.setCarry(false)
cpu.A = 0x40
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x80, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestROLZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x26, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x0080))
}
func TestROLZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x36, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x0082, 0x01)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x0082))
}
func TestROLAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x2E, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8000))
}
func TestROLAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x3E, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x01)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x8002))
}
//// ROR
func TestRORAccumulator(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x6A}, 0x0300)
cpu.A = 0x02
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x01, cpu.A)
}
func TestRORAccumulatorZeroAndCarry(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x6A}, 0x0300)
cpu.setCarry(false)
cpu.A = 0x01
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
assert.True(t, cpu.getCarry())
}
func TestRORAccumulatorNegative(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x6A}, 0x0300)
cpu.setCarry(true)
cpu.A = 0x01
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0x80, cpu.A)
assert.True(t, cpu.getNegative())
}
func TestRORZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x66, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x01, cpu.Bus.ReadByte(0x0080))
}
func TestRORZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x76, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x0082, 0x02)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0x01, cpu.Bus.ReadByte(0x0082))
}
func TestRORAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x6E, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x02)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x01, cpu.Bus.ReadByte(0x8000))
}
func TestRORAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x7E, 0x00, 0x80}, 0x0300)
cpu.X = 0x02
cpu.Bus.WriteByte(0x8002, 0x02)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0x01, cpu.Bus.ReadByte(0x8002))
}
/// CMP
func TestCMPImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xC9, 0x42}, 0x0300)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xC9, 0x42}, 0x0300)
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xC9, 0x0A}, 0x0300)
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xC5, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x42)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xC5, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x42)
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xC5, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x0A)
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPZeropageX(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xD5, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0082, 0x42)
cpu.X = 0x02
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xD5, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0082, 0x42)
cpu.X = 0x02
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xD5, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0082, 0x0A)
cpu.X = 0x02
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xCD, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x42)
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xCD, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x42)
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xCD, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x0A)
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPAbsoluteX(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xDD, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8002, 0x42)
cpu.X = 0x02
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xDD, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8002, 0x42)
cpu.X = 0x02
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xDD, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8002, 0x0A)
cpu.X = 0x02
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPAbsoluteY(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xD9, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8002, 0x42)
cpu.Y = 0x02
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xD9, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8002, 0x42)
cpu.Y = 0x02
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xD9, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8002, 0x0A)
cpu.Y = 0x02
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPIndirectX(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xC1, 0x80}, 0x0300)
cpu.Bus.Write16(0x0082, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x42)
cpu.X = 0x02
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xC1, 0x80}, 0x0300)
cpu.Bus.Write16(0x0082, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x42)
cpu.X = 0x02
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xC1, 0x80}, 0x0300)
cpu.Bus.Write16(0x0082, 0xC000)
cpu.Bus.WriteByte(0xC000, 0x0A)
cpu.X = 0x02
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCMPIndirectY(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xD1, 0x80}, 0x0300)
cpu.Bus.Write16(0x0080, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x42)
cpu.Y = 0x02
cpu.A = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xD1, 0x80}, 0x0300)
cpu.Bus.Write16(0x0080, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x42)
cpu.X = 0x02
cpu.A = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xD1, 0x80}, 0x0300)
cpu.Bus.Write16(0x0080, 0xC000)
cpu.Bus.WriteByte(0xC002, 0x0A)
cpu.X = 0x02
cpu.A = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
//// CPX
func TestCPXImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xE0, 0x42}, 0x0300)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xE0, 0x42}, 0x0300)
cpu.X = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xE0, 0x0A}, 0x0300)
cpu.X = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCPXZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xE4, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x42)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xE4, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x42)
cpu.X = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xE4, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x0A)
cpu.X = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCPXAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xEC, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x42)
cpu.X = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xEC, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x42)
cpu.X = 0x43
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xEC, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x0A)
cpu.X = 0x08
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
//// CPY
func TestCPYImmediate(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xC0, 0x42}, 0x0300)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xC0, 0x42}, 0x0300)
cpu.Y = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xC0, 0x0A}, 0x0300)
cpu.Y = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCPYZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xC4, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x42)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xC4, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x42)
cpu.Y = 0x43
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xC4, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x0080, 0x0A)
cpu.Y = 0x08
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
func TestCPYAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
// Equality
cpu.LoadProgram([]byte{0xCC, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x42)
cpu.Y = 0x42
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Greater Than
cpu.LoadProgram([]byte{0xCC, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x42)
cpu.Y = 0x43
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.True(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.False(t, cpu.getNegative())
// Less Than
cpu.LoadProgram([]byte{0xCC, 0x00, 0x80}, 0x0300)
cpu.Bus.WriteByte(0x8000, 0x0A)
cpu.Y = 0x08
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.False(t, cpu.getCarry())
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
}
//// BRK
func TestBRK(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x00}, 0x0300)
cpu.Bus.Write16(IrqVector, 0x1234)
cpu.SP = 0xFF
status := cpu.P
cpu.Step()
assert.Equal(t, 0x1234, cpu.PC)
assert.Equal(t, 0x03, cpu.Bus.ReadByte(0x01FF))
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x01FE))
assert.Equal(t, status, cpu.Bus.ReadByte(0x01FD))
assert.True(t, cpu.getBreak())
}
//// BCC
func TestBCC(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0x90, 0x05}, 0x0300)
cpu.setCarry(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x90, 0x05}, 0x0300)
cpu.setCarry(false)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0x90, 0xfb}, 0x0300)
cpu.setCarry(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x90, 0xFB}, 0x0300)
cpu.setCarry(false)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
}
//// BCS
func TestBCS(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0xB0, 0x05}, 0x0300)
cpu.setCarry(true)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0xB0, 0x05}, 0x0300)
cpu.setCarry(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0xB0, 0xfb}, 0x0300)
cpu.setCarry(true)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0xB0, 0xFB}, 0x0300)
cpu.setCarry(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
}
//// BNE
func TestBNE(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0xD0, 0x05}, 0x0300)
cpu.setZero(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0xD0, 0x05}, 0x0300)
cpu.setZero(false)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0xD0, 0xfb}, 0x0300)
cpu.setZero(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0xD0, 0xFB}, 0x0300)
cpu.setZero(false)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
}
//// BEQ
func TestBEQ(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0xF0, 0x05}, 0x0300)
cpu.setZero(true)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0xF0, 0x05}, 0x0300)
cpu.setZero(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0xF0, 0xfb}, 0x0300)
cpu.setZero(true)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0xF0, 0xFB}, 0x0300)
cpu.setZero(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
}
//// BPL
func TestBPL(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0x10, 0x05}, 0x0300)
cpu.setNegative(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x10, 0x05}, 0x0300)
cpu.setNegative(false)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0x10, 0xfb}, 0x0300)
cpu.setNegative(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x10, 0xFB}, 0x0300)
cpu.setNegative(false)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
}
//// BMI
func TestBMI(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0x30, 0x05}, 0x0300)
cpu.setNegative(true)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x30, 0x05}, 0x0300)
cpu.setNegative(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0x30, 0xfb}, 0x0300)
cpu.setNegative(true)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x30, 0xFB}, 0x0300)
cpu.setNegative(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
}
//// BVC
func TestBVC(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0x50, 0x05}, 0x0300)
cpu.setOverflow(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x50, 0x05}, 0x0300)
cpu.setOverflow(false)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0x50, 0xfb}, 0x0300)
cpu.setOverflow(true)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x50, 0xFB}, 0x0300)
cpu.setOverflow(false)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
}
//// BVS
func TestBVS(t *testing.T) {
cpu, _, _ := NewRamMachine()
/// Positive offset
// Carry set
cpu.LoadProgram([]byte{0x70, 0x05}, 0x0300)
cpu.setOverflow(true)
cpu.Step()
// 0x0302 + 0x05 = 0x0307
assert.Equal(t, 0x0307, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x70, 0x05}, 0x0300)
cpu.setOverflow(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
/// Negative offset
// Carry set
cpu.LoadProgram([]byte{0x70, 0xfb}, 0x0300)
cpu.setOverflow(true)
cpu.Step()
// 0x0302 + 0xFB => 0x0302 - 0x05 => 0x02FD
assert.Equal(t, 0x02FD, cpu.PC)
// Carry not set
cpu.LoadProgram([]byte{0x70, 0xFB}, 0x0300)
cpu.setOverflow(false)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
}
//// BIT
func TestBITZeropage(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.Bus.WriteByte(0x0000, 0xC0)
cpu.Bus.WriteByte(0x0010, 0x40)
cpu.Bus.WriteByte(0x0020, 0x80)
cpu.LoadProgram([]byte{0x24, 0x00}, 0x0300)
cpu.A = 0x01
cpu.Step()
assert.True(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x24, 0x20}, 0x0300)
cpu.A = 0x40
cpu.Step()
assert.True(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.False(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x24, 0x10}, 0x0300)
cpu.A = 0x80
cpu.Step()
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x24, 0x00}, 0x0300)
cpu.A = 0xC0
cpu.Step()
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x24, 0x00}, 0x0300)
cpu.A = 0xFF
cpu.Step()
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
}
func TestBITAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.Bus.WriteByte(0xC000, 0xC0)
cpu.Bus.WriteByte(0xC010, 0x40)
cpu.Bus.WriteByte(0xC020, 0x80)
cpu.LoadProgram([]byte{0x2C, 0x00, 0xC0}, 0x0300)
cpu.A = 0x01
cpu.Step()
assert.True(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x2C, 0x20, 0xC0}, 0x0300)
cpu.A = 0x40
cpu.Step()
assert.True(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.False(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x2C, 0x10, 0xC0}, 0x0300)
cpu.A = 0x80
cpu.Step()
assert.True(t, cpu.getZero())
assert.False(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x2C, 0x00, 0xC0}, 0x0300)
cpu.A = 0xC0
cpu.Step()
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
cpu.LoadProgram([]byte{0x2C, 0x00, 0xC0}, 0x0300)
cpu.A = 0xFF
cpu.Step()
assert.False(t, cpu.getZero())
assert.True(t, cpu.getNegative())
assert.True(t, cpu.getOverflow())
}
//// PHP
func TestPHP(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x08}, 0x0300)
cpu.SP = 0xFF
cpu.P = 0xB5
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xFE, cpu.SP)
assert.Equal(t, 0xB5, cpu.Bus.ReadByte(0x01FF))
}
//// PLP
func TestPLP(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x28}, 0x0300)
cpu.stackPush(0xB5)
cpu.P = 0x34
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xFF, cpu.SP)
assert.Equal(t, 0xB5, cpu.P)
}
//// PHA
func TestPHA(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x48}, 0x0300)
cpu.SP = 0xFF
cpu.A = 0xB5
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xFE, cpu.SP)
assert.Equal(t, 0xB5, cpu.Bus.ReadByte(0x01FF))
}
//// PLP
func TestPLA(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x68, 0x68, 0x68}, 0x0300)
cpu.stackPush(0x42)
cpu.Step()
assert.Equal(t, 0x0301, cpu.PC)
assert.Equal(t, 0xFF, cpu.SP)
assert.Equal(t, 0x42, cpu.A)
cpu.stackPush(0xB5)
cpu.Step()
assert.Equal(t, 0x0302, cpu.PC)
assert.Equal(t, 0xFF, cpu.SP)
assert.Equal(t, 0xB5, cpu.A)
assert.True(t, cpu.getNegative())
cpu.stackPush(0x00)
cpu.Step()
assert.Equal(t, 0x0303, cpu.PC)
assert.Equal(t, 0xFF, cpu.SP)
assert.Equal(t, 0x00, cpu.A)
assert.True(t, cpu.getZero())
}
//// JMP
func TestJMPAbsolute(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x4C, 0x34, 0x12}, 0x0300)
cpu.Step()
assert.Equal(t, 0x1234, cpu.PC)
}
func TestJMPIndirect(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x6C, 0x00, 0xC0}, 0x0300)
cpu.Bus.Write16(0xC000, 0x1234)
cpu.Step()
assert.Equal(t, 0x1234, cpu.PC)
}
//// JSR
func TestJSR(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x20, 0x34, 0x12}, 0x0300)
cpu.SP = 0xFF
cpu.Step()
assert.Equal(t, 0x1234, cpu.PC)
assert.Equal(t, 0xFD, cpu.SP)
// We expect PC - 1 (e.g. 3rd byte of JSR) to be on the stack
assert.Equal(t, 0x03, cpu.Bus.ReadByte(0x1FF))
assert.Equal(t, 0x02, cpu.Bus.ReadByte(0x1FE))
}
//// RTS
func TestRTS(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x60}, 0x0300)
cpu.P = 0x34
cpu.stackPush(0x12) // PC HI
cpu.stackPush(0x34) // PC LO
cpu.Step()
assert.Equal(t, 0x1234+1, cpu.PC)
assert.Equal(t, 0x34, cpu.P)
}
//// RTI
func TestRTI(t *testing.T) {
cpu, _, _ := NewRamMachine()
cpu.LoadProgram([]byte{0x40}, 0x0300)
cpu.stackPush(0x12) // PC HI
cpu.stackPush(0x34) // PC LO
cpu.stackPush(0x5B) // P
cpu.Step()
assert.Equal(t, 0x1234, cpu.PC)
assert.Equal(t, 0x5B|0x20, cpu.P)
}
// Run this last, as the full suite takes ±10 seconds to run at
// maximum speed
func TestKlausDormann6502(t *testing.T) {
fmt.Println("Running Klaus Dormann' 6502 functional tests. This may take some time...")
cpu, _, _ := NewRamMachine()
cpu.LoadProgram(loadProgram("test/6502_functional_test.bin"), 0x0000)
cpu.PC = 0x0400
prevPC := uint16(0x0400)
for {
cpu.Step()
if cpu.PC == prevPC {
if cpu.PC != 0x3399 {
str := "Looping PC detected at PC 0x%04X. We've hit a failing Klaus Dormann test."
panic(fmt.Sprintf(str, cpu.PC))
} else {
fmt.Println("Klaus Dormann's 6502 functional tests passed.")
break
}
}
prevPC = cpu.PC
}
}