mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-22 09:30:19 +00:00
Support CMP, CPX and CPY
This commit is contained in:
parent
9e73ad1850
commit
1379fda5b5
BIN
debug.test
Executable file
BIN
debug.test
Executable file
Binary file not shown.
48
execute.go
48
execute.go
@ -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:
|
TODO:
|
||||||
|
|
||||||
@ -191,11 +210,6 @@ AND
|
|||||||
ORA
|
ORA
|
||||||
EOR
|
EOR
|
||||||
|
|
||||||
BIT
|
|
||||||
CMP
|
|
||||||
CPX
|
|
||||||
CPY
|
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
JMP
|
JMP
|
||||||
@ -211,6 +225,26 @@ PLP
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var opcodes = [256]opcode{
|
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)},
|
0x2A: opcode{"ROL", 1, 2, buildShift(modeAccumulator, true, true)},
|
||||||
0x26: opcode{"ROL", 2, 5, buildShift(modeZeroPage, true, true)},
|
0x26: opcode{"ROL", 2, 5, buildShift(modeZeroPage, true, true)},
|
||||||
0x36: opcode{"ROL", 2, 6, buildShift(modeZeroPageX, 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)},
|
0xAD: opcode{"LDA", 3, 4, buildOpLoad(modeAbsolute, regA)},
|
||||||
0xBD: opcode{"LDA", 3, 4, buildOpLoad(modeAbsoluteX, regA)}, // Extra cycles
|
0xBD: opcode{"LDA", 3, 4, buildOpLoad(modeAbsoluteX, regA)}, // Extra cycles
|
||||||
0xB9: opcode{"LDA", 3, 4, buildOpLoad(modeAbsoluteY, 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)},
|
0xA2: opcode{"LDX", 2, 2, buildOpLoad(modeImmediate, regX)},
|
||||||
0xA6: opcode{"LDX", 2, 3, buildOpLoad(modeZeroPage, regX)},
|
0xA6: opcode{"LDX", 2, 3, buildOpLoad(modeZeroPage, regX)},
|
||||||
0xB6: opcode{"LDX", 2, 4, buildOpLoad(modeZeroPageY, regX)},
|
0xB6: opcode{"LDX", 2, 4, buildOpLoad(modeZeroPageY, regX)},
|
||||||
0xAE: opcode{"LDX", 3, 4, buildOpLoad(modeAbsolute, regX)},
|
0xAE: opcode{"LDX", 3, 4, buildOpLoad(modeAbsolute, regX)},
|
||||||
0xBE: opcode{"LDX", 3, 4, buildOpLoad(modeAbsoluteY, regX)}, // Extra cycles
|
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)},
|
0xA0: opcode{"LDY", 2, 2, buildOpLoad(modeImmediate, regY)},
|
||||||
0xA4: opcode{"LDY", 2, 3, buildOpLoad(modeZeroPage, regY)},
|
0xA4: opcode{"LDY", 2, 3, buildOpLoad(modeZeroPage, regY)},
|
||||||
|
@ -153,6 +153,7 @@ func TestTransfer(t *testing.T) {
|
|||||||
if s.registers.getSP() != 0xB4 {
|
if s.registers.getSP() != 0xB4 {
|
||||||
t.Error("Error in TXS")
|
t.Error("Error in TXS")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.registers.setY(0xB5)
|
s.registers.setY(0xB5)
|
||||||
executeLine(&s, []uint8{0x98})
|
executeLine(&s, []uint8{0x98})
|
||||||
if s.registers.getA() != 0xB5 {
|
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) {
|
func TestBranch(t *testing.T) {
|
||||||
var s state
|
var s state
|
||||||
s.registers.setPC(0xC600)
|
s.registers.setPC(0xC600)
|
||||||
|
Loading…
Reference in New Issue
Block a user