Support CMP, CPX and CPY

This commit is contained in:
Ivan Izaguirre 2019-01-30 23:01:47 +01:00
parent 9e73ad1850
commit 1379fda5b5
3 changed files with 99 additions and 7 deletions

BIN
debug.test Executable file

Binary file not shown.

View File

@ -181,6 +181,25 @@ func buildOpBranch(flag uint8, value bool) opFunc {
}
}
func buildOpBit(addressMode int) opFunc {
return func(s *state, line []uint8, opcode opcode) {
value, _ := resolveWithAddressMode(s, line, addressMode)
acc := s.registers.getA()
s.registers.updateFlag(flagZ, value&acc == 0)
s.registers.updateFlag(flagN, value&(1<<7) != 0)
s.registers.updateFlag(flagV, value&(1<<6) != 0)
}
}
func buildOpCompare(addressMode int, reg int) opFunc {
return func(s *state, line []uint8, opcode opcode) {
value, _ := resolveWithAddressMode(s, line, addressMode)
reference := s.registers.getRegister(reg)
s.registers.updateFlagZN(reference - value)
s.registers.updateFlag(flagC, reference >= value)
}
}
/*
TODO:
@ -191,11 +210,6 @@ AND
ORA
EOR
BIT
CMP
CPX
CPY
BRK
JMP
@ -211,6 +225,26 @@ PLP
*/
var opcodes = [256]opcode{
0x24: opcode{"BIT", 2, 3, buildOpBit(modeZeroPage)},
0x2C: opcode{"BIT", 2, 3, buildOpBit(modeAbsolute)},
0xC9: opcode{"CMP", 2, 2, buildOpCompare(modeImmediate, regA)},
0xC5: opcode{"CMP", 2, 3, buildOpCompare(modeZeroPage, regA)},
0xD5: opcode{"CMP", 2, 4, buildOpCompare(modeZeroPageX, regA)},
0xCD: opcode{"CMP", 3, 4, buildOpCompare(modeAbsolute, regA)},
0xDD: opcode{"CMP", 3, 4, buildOpCompare(modeAbsoluteX, regA)}, // Extra cycles
0xD9: opcode{"CMP", 3, 4, buildOpCompare(modeAbsoluteY, regA)}, // Extra cycles
0xC1: opcode{"CMP", 2, 6, buildOpCompare(modeIndexedIndirectX, regA)},
0xD1: opcode{"CMP", 2, 5, buildOpCompare(modeIndirectIndexedY, regA)}, // Extra cycles
0xE0: opcode{"CPX", 2, 2, buildOpCompare(modeImmediate, regX)},
0xE4: opcode{"CPX", 2, 3, buildOpCompare(modeZeroPage, regX)},
0xEC: opcode{"CPX", 3, 4, buildOpCompare(modeAbsolute, regX)},
0xC0: opcode{"CPY", 2, 2, buildOpCompare(modeImmediate, regY)},
0xC4: opcode{"CPY", 2, 3, buildOpCompare(modeZeroPage, regY)},
0xCC: opcode{"CPY", 3, 4, buildOpCompare(modeAbsolute, regY)},
0x2A: opcode{"ROL", 1, 2, buildShift(modeAccumulator, true, true)},
0x26: opcode{"ROL", 2, 5, buildShift(modeZeroPage, true, true)},
0x36: opcode{"ROL", 2, 6, buildShift(modeZeroPageX, true, true)},
@ -272,14 +306,14 @@ var opcodes = [256]opcode{
0xAD: opcode{"LDA", 3, 4, buildOpLoad(modeAbsolute, regA)},
0xBD: opcode{"LDA", 3, 4, buildOpLoad(modeAbsoluteX, regA)}, // Extra cycles
0xB9: opcode{"LDA", 3, 4, buildOpLoad(modeAbsoluteY, regA)}, // Extra cycles
0xA1: opcode{"LDA", 2, 6, buildOpLoad(modeIndexedIndirectX, regA)},
0xB1: opcode{"LDA", 2, 5, buildOpLoad(modeIndirectIndexedY, regA)}, // Extra cycles
0xA2: opcode{"LDX", 2, 2, buildOpLoad(modeImmediate, regX)},
0xA6: opcode{"LDX", 2, 3, buildOpLoad(modeZeroPage, regX)},
0xB6: opcode{"LDX", 2, 4, buildOpLoad(modeZeroPageY, regX)},
0xAE: opcode{"LDX", 3, 4, buildOpLoad(modeAbsolute, regX)},
0xBE: opcode{"LDX", 3, 4, buildOpLoad(modeAbsoluteY, regX)}, // Extra cycles
0xA1: opcode{"LDX", 2, 6, buildOpLoad(modeIndexedIndirectX, regA)},
0xB1: opcode{"LDX", 2, 5, buildOpLoad(modeIndirectIndexedY, regA)}, // Extra cycles
0xA0: opcode{"LDY", 2, 2, buildOpLoad(modeImmediate, regY)},
0xA4: opcode{"LDY", 2, 3, buildOpLoad(modeZeroPage, regY)},

View File

@ -153,6 +153,7 @@ func TestTransfer(t *testing.T) {
if s.registers.getSP() != 0xB4 {
t.Error("Error in TXS")
}
s.registers.setY(0xB5)
executeLine(&s, []uint8{0x98})
if s.registers.getA() != 0xB5 {
@ -238,6 +239,63 @@ func TestClearSetFlag(t *testing.T) {
}
func TestCompare(t *testing.T) {
var s state
s.registers.setA(0x02)
executeLine(&s, []uint8{0xC9, 0x01})
if s.registers.getP() != 0x01 {
t.Errorf("Error in CMP <. %v", s.registers)
}
executeLine(&s, []uint8{0xC9, 0x02})
if s.registers.getP() != 0x03 {
t.Errorf("Error in CMP =. %v", s.registers)
}
executeLine(&s, []uint8{0xC9, 0x03})
if s.registers.getP() != 0x80 {
t.Errorf("Error in CMP >. %v", s.registers)
}
s.registers.setX(0x04)
executeLine(&s, []uint8{0xE0, 0x05})
if s.registers.getP() != 0x80 {
t.Errorf("Error in CPX >. %v", s.registers)
}
s.registers.setY(0x08)
executeLine(&s, []uint8{0xC0, 0x09})
if s.registers.getP() != 0x80 {
t.Errorf("Error in CPY >. %v", s.registers)
}
}
func TestBit(t *testing.T) {
var s state
s.registers.setA(0x0F)
s.memory[0x0040] = 0xF0
executeLine(&s, []uint8{0x24, 0x40})
if s.registers.getP() != 0xC2 {
t.Errorf("Error in BIT. %v", s.registers)
}
s.registers.setA(0xF0)
s.memory[0x0040] = 0xF0
executeLine(&s, []uint8{0x24, 0x40})
if s.registers.getP() != 0xC0 {
t.Errorf("Error in BIT, 2. %v", s.registers)
}
s.registers.setA(0xF0)
s.memory[0x01240] = 0x80
executeLine(&s, []uint8{0x2C, 0x40, 0x12})
if s.registers.getP() != 0x80 {
t.Errorf("Error in BIT, 2. %v", s.registers)
}
}
func TestBranch(t *testing.T) {
var s state
s.registers.setPC(0xC600)