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:
|
||||
|
||||
@ -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)},
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user