mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-22 09:30:19 +00:00
Support for ADC and SBC without BCD
This commit is contained in:
parent
d56bea182f
commit
1c1bd79f13
76
execute.go
76
execute.go
@ -213,15 +213,43 @@ func buildOpLogic(addressMode int, operation func(uint8, uint8) uint8) opFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildOpAdd(addressMode int) opFunc {
|
||||||
|
return func(s *state, line []uint8, opcode opcode) {
|
||||||
|
value, _ := resolveWithAddressMode(s, line, addressMode)
|
||||||
|
if s.registers.getFlag(flagD) {
|
||||||
|
// TODO BCD
|
||||||
|
} else {
|
||||||
|
total := uint16(s.registers.getA()) +
|
||||||
|
uint16(value) +
|
||||||
|
uint16(s.registers.getFlagBit(flagC))
|
||||||
|
truncated := uint8(total)
|
||||||
|
s.registers.setA(truncated)
|
||||||
|
s.registers.updateFlagZN(truncated)
|
||||||
|
s.registers.updateFlag(flagC, total > 0xFF)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildOpSub(addressMode int) opFunc {
|
||||||
|
return func(s *state, line []uint8, opcode opcode) {
|
||||||
|
value, _ := resolveWithAddressMode(s, line, addressMode)
|
||||||
|
if s.registers.getFlag(flagD) {
|
||||||
|
// TODO BCD
|
||||||
|
} else {
|
||||||
|
total := 0x100 + uint16(s.registers.getA()) -
|
||||||
|
uint16(value) -
|
||||||
|
uint16(s.registers.getFlagBit(flagC))
|
||||||
|
truncated := uint8(total)
|
||||||
|
s.registers.setA(truncated)
|
||||||
|
s.registers.updateFlagZN(truncated)
|
||||||
|
s.registers.updateFlag(flagC, total <= 0xFF)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
|
http://www.6502.org/tutorials/decimal_mode.html
|
||||||
ADC
|
|
||||||
SBC
|
|
||||||
|
|
||||||
AND
|
|
||||||
ORA
|
|
||||||
EOR
|
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@ -238,6 +266,15 @@ PLP
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var opcodes = [256]opcode{
|
var opcodes = [256]opcode{
|
||||||
|
0x09: opcode{"ORA", 2, 2, buildOpLogic(modeImmediate, operationOr)},
|
||||||
|
0x05: opcode{"ORA", 2, 3, buildOpLogic(modeZeroPage, operationOr)},
|
||||||
|
0x15: opcode{"ORA", 2, 4, buildOpLogic(modeZeroPageX, operationOr)},
|
||||||
|
0x0D: opcode{"ORA", 3, 4, buildOpLogic(modeAbsolute, operationOr)},
|
||||||
|
0x1D: opcode{"ORA", 3, 4, buildOpLogic(modeAbsoluteX, operationOr)}, // Extra cycles
|
||||||
|
0x19: opcode{"ORA", 3, 4, buildOpLogic(modeAbsoluteY, operationOr)}, // Extra cycles
|
||||||
|
0x01: opcode{"ORA", 2, 6, buildOpLogic(modeIndexedIndirectX, operationOr)},
|
||||||
|
0x11: opcode{"ORA", 2, 5, buildOpLogic(modeIndirectIndexedY, operationOr)}, // Extra cycles
|
||||||
|
|
||||||
0x29: opcode{"AND", 2, 2, buildOpLogic(modeImmediate, operationAnd)},
|
0x29: opcode{"AND", 2, 2, buildOpLogic(modeImmediate, operationAnd)},
|
||||||
0x25: opcode{"AND", 2, 3, buildOpLogic(modeZeroPage, operationAnd)},
|
0x25: opcode{"AND", 2, 3, buildOpLogic(modeZeroPage, operationAnd)},
|
||||||
0x35: opcode{"AND", 2, 4, buildOpLogic(modeZeroPageX, operationAnd)},
|
0x35: opcode{"AND", 2, 4, buildOpLogic(modeZeroPageX, operationAnd)},
|
||||||
@ -256,14 +293,23 @@ var opcodes = [256]opcode{
|
|||||||
0x41: opcode{"EOR", 2, 6, buildOpLogic(modeIndexedIndirectX, operationXor)},
|
0x41: opcode{"EOR", 2, 6, buildOpLogic(modeIndexedIndirectX, operationXor)},
|
||||||
0x51: opcode{"EOR", 2, 5, buildOpLogic(modeIndirectIndexedY, operationXor)}, // Extra cycles
|
0x51: opcode{"EOR", 2, 5, buildOpLogic(modeIndirectIndexedY, operationXor)}, // Extra cycles
|
||||||
|
|
||||||
0x09: opcode{"ORA", 2, 2, buildOpLogic(modeImmediate, operationOr)},
|
0x69: opcode{"ADC", 2, 2, buildOpAdd(modeImmediate)},
|
||||||
0x05: opcode{"ORA", 2, 3, buildOpLogic(modeZeroPage, operationOr)},
|
0x65: opcode{"ADC", 2, 3, buildOpAdd(modeZeroPage)},
|
||||||
0x15: opcode{"ORA", 2, 4, buildOpLogic(modeZeroPageX, operationOr)},
|
0x75: opcode{"ADC", 2, 4, buildOpAdd(modeZeroPageX)},
|
||||||
0x0D: opcode{"ORA", 3, 4, buildOpLogic(modeAbsolute, operationOr)},
|
0x6D: opcode{"ADC", 3, 4, buildOpAdd(modeAbsolute)},
|
||||||
0x1D: opcode{"ORA", 3, 4, buildOpLogic(modeAbsoluteX, operationOr)}, // Extra cycles
|
0x7D: opcode{"ADC", 3, 4, buildOpAdd(modeAbsoluteX)}, // Extra cycles
|
||||||
0x19: opcode{"ORA", 3, 4, buildOpLogic(modeAbsoluteY, operationOr)}, // Extra cycles
|
0x79: opcode{"ADC", 3, 4, buildOpAdd(modeAbsoluteY)}, // Extra cycles
|
||||||
0x01: opcode{"ORA", 2, 6, buildOpLogic(modeIndexedIndirectX, operationOr)},
|
0x61: opcode{"ADC", 2, 6, buildOpAdd(modeIndexedIndirectX)},
|
||||||
0x11: opcode{"ORA", 2, 5, buildOpLogic(modeIndirectIndexedY, operationOr)}, // Extra cycles
|
0x71: opcode{"ADC", 2, 5, buildOpAdd(modeIndirectIndexedY)}, // Extra cycles
|
||||||
|
|
||||||
|
0xE9: opcode{"SBC", 2, 2, buildOpSub(modeImmediate)},
|
||||||
|
0xE5: opcode{"SBC", 2, 3, buildOpSub(modeZeroPage)},
|
||||||
|
0xF5: opcode{"SBC", 2, 4, buildOpSub(modeZeroPageX)},
|
||||||
|
0xED: opcode{"SBC", 3, 4, buildOpSub(modeAbsolute)},
|
||||||
|
0xFD: opcode{"SBC", 3, 4, buildOpSub(modeAbsoluteX)}, // Extra cycles
|
||||||
|
0xF9: opcode{"SBC", 3, 4, buildOpSub(modeAbsoluteY)}, // Extra cycles
|
||||||
|
0xE1: opcode{"SBC", 2, 6, buildOpSub(modeIndexedIndirectX)},
|
||||||
|
0xF1: opcode{"SBC", 2, 5, buildOpSub(modeIndirectIndexedY)}, // Extra cycles
|
||||||
|
|
||||||
0x24: opcode{"BIT", 2, 3, buildOpBit(modeZeroPage)},
|
0x24: opcode{"BIT", 2, 3, buildOpBit(modeZeroPage)},
|
||||||
0x2C: opcode{"BIT", 2, 3, buildOpBit(modeAbsolute)},
|
0x2C: opcode{"BIT", 2, 3, buildOpBit(modeAbsolute)},
|
||||||
|
@ -239,7 +239,7 @@ func TestClearSetFlag(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testLogic(t *testing.T) {
|
func TestLogic(t *testing.T) {
|
||||||
var s state
|
var s state
|
||||||
|
|
||||||
s.registers.setA(0xF0)
|
s.registers.setA(0xF0)
|
||||||
@ -261,6 +261,75 @@ func testLogic(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAdd(t *testing.T) {
|
||||||
|
var s state
|
||||||
|
|
||||||
|
s.registers.setA(0xA0)
|
||||||
|
s.registers.clearFlag(flagC)
|
||||||
|
executeLine(&s, []uint8{0x69, 0x0B})
|
||||||
|
if s.registers.getA() != 0xAB {
|
||||||
|
t.Errorf("Error in ADC A0 + 0B. %v", s.registers)
|
||||||
|
}
|
||||||
|
if s.registers.getFlag(flagC) {
|
||||||
|
t.Errorf("Error in carry ADC A0 + 0B. %v", s.registers)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.registers.setA(0xFF)
|
||||||
|
s.registers.clearFlag(flagC)
|
||||||
|
executeLine(&s, []uint8{0x69, 0x02})
|
||||||
|
if s.registers.getA() != 0x01 {
|
||||||
|
t.Errorf("Error in ADC A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
if !s.registers.getFlag(flagC) {
|
||||||
|
t.Errorf("Error in carry ADC A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.registers.setA(0xA0)
|
||||||
|
s.registers.setFlag(flagC)
|
||||||
|
executeLine(&s, []uint8{0x69, 0x01})
|
||||||
|
if s.registers.getA() != 0xA2 {
|
||||||
|
t.Errorf("Error in ADC C + A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
if s.registers.getFlag(flagC) {
|
||||||
|
t.Errorf("Error in carry ADC C + A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSub(t *testing.T) {
|
||||||
|
var s state
|
||||||
|
|
||||||
|
s.registers.setA(0x09)
|
||||||
|
s.registers.clearFlag(flagC)
|
||||||
|
executeLine(&s, []uint8{0xE9, 0x05})
|
||||||
|
if s.registers.getA() != 0x04 {
|
||||||
|
t.Errorf("Error in SBC A0 + 0B. %v", s.registers)
|
||||||
|
}
|
||||||
|
if s.registers.getFlag(flagC) {
|
||||||
|
t.Errorf("Error in carry SBC A0 + 0B. %v", s.registers)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.registers.setA(0x01)
|
||||||
|
s.registers.clearFlag(flagC)
|
||||||
|
executeLine(&s, []uint8{0xE9, 0x02})
|
||||||
|
if s.registers.getA() != 0xFF {
|
||||||
|
t.Errorf("Error in SBC A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
if !s.registers.getFlag(flagC) {
|
||||||
|
t.Errorf("Error in carry SBC A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.registers.setA(0x08)
|
||||||
|
s.registers.setFlag(flagC)
|
||||||
|
executeLine(&s, []uint8{0xE9, 0x02})
|
||||||
|
if s.registers.getA() != 0x05 {
|
||||||
|
t.Errorf("Error in SBC C + A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
if s.registers.getFlag(flagC) {
|
||||||
|
t.Errorf("Error in carry SBC C + A0 + 0B with carry. %v", s.registers)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestCompare(t *testing.T) {
|
func TestCompare(t *testing.T) {
|
||||||
var s state
|
var s state
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user