Fixed ROL A, added ROR

This commit is contained in:
Ivan Izaguirre 2019-01-28 23:10:23 +01:00
parent aa5aab3526
commit 9b0dac5ac8
3 changed files with 60 additions and 15 deletions

View File

@ -68,6 +68,7 @@ func resolveWithAddressMode(s *state, line []uint8, addressMode int) (value uint
switch addressMode {
case modeAccumulator:
value = s.registers.getA()
hasAddress = false
case modeImmediate:
value = line[1]
hasAddress = false
@ -97,16 +98,24 @@ func resolveWithAddressMode(s *state, line []uint8, addressMode int) (value uint
return
}
func buildRotateLeft(addressMode int) opFunc {
func buildRotate(addressMode int, isLeft bool) opFunc {
return func(s *state, line []uint8, opcode opcode) {
value, hasAddress, address := resolveWithAddressMode(s, line, addressMode)
carry := value >= (7<<1)
value <<= 1
value += s.registers.getFlagBit(flagC)
oldCarry := s.registers.getFlagBit(flagC)
var carry bool
if isLeft {
carry = (value & 0x80) != 0
value <<= 1
value += oldCarry
} else {
carry = (value & 0x01) != 0
value >>= 1
value += oldCarry << 7
}
s.registers.updateFlag(flagC, carry)
s.registers.updateFlagZN(value)
if hasAddress {
s.memory[address] = value
} else {
@ -124,11 +133,18 @@ func buildOpLoad(addressMode int, regDst int) opFunc {
}
var opcodes = [256]opcode{
0x26: opcode{"ROL", 2, 5, buildRotateLeft(modeZeroPage)},
0x2A: opcode{"ROL", 1, 2, buildRotateLeft(modeAccumulator)},
0x2E: opcode{"ROL", 3, 6, buildRotateLeft(modeAbsolute)},
0x36: opcode{"ROL", 2, 6, buildRotateLeft(modeZeroPageX)},
0x3E: opcode{"ROL", 3, 7, buildRotateLeft(modeAbsoluteX)},
0x26: opcode{"ROL", 2, 5, buildRotate(modeZeroPage, true)},
0x2A: opcode{"ROL", 1, 2, buildRotate(modeAccumulator, true)},
0x2E: opcode{"ROL", 3, 6, buildRotate(modeAbsolute, true)},
0x36: opcode{"ROL", 2, 6, buildRotate(modeZeroPageX, true)},
0x3E: opcode{"ROL", 3, 7, buildRotate(modeAbsoluteX, true)},
0x66: opcode{"ROR", 2, 5, buildRotate(modeZeroPage, false)},
0x6A: opcode{"ROR", 1, 2, buildRotate(modeAccumulator, false)},
0x6E: opcode{"ROR", 3, 6, buildRotate(modeAbsolute, false)},
0x76: opcode{"ROR", 2, 6, buildRotate(modeZeroPageX, false)},
0x7E: opcode{"ROR", 3, 7, buildRotate(modeAbsoluteX, false)},
0x88: opcode{"DEY", 1, 2, buildOpIncDecRegister(regY, false)},
0x8A: opcode{"TXA", 1, 2, buildOpTransfer(regX, regA)},
0x98: opcode{"TYA", 1, 2, buildOpTransfer(regY, regA)},

View File

@ -128,13 +128,13 @@ func TestTransfer(t *testing.T) {
}
}
func TestIncDec(t * testing.T) {
func TestIncDec(t *testing.T) {
var s state
s.registers.setX(0x7E)
executeLine(&s, []uint8{0xE8})
if s.registers.getX() != 0x7F {
t.Errorf("Error in INX %v", s.registers.getX())
t.Errorf("Error in INX")
}
s.registers.setY(0xFC)
@ -145,5 +145,28 @@ func TestIncDec(t * testing.T) {
if s.registers.getP() != flagN {
t.Error("Error in DEY flags")
}
}
func TestRotate(t *testing.T) {
var s state
s.registers.setA(0xF0)
executeLine(&s, []uint8{0x2A})
if s.registers.getA() != 0xE0 {
t.Errorf("Error in ROL")
}
if !s.registers.getFlag(flagC) {
t.Errorf("Error in ROL carry. %v", s.registers)
}
s.registers.setFlag(flagC)
s.registers.setA(0x0F)
executeLine(&s, []uint8{0x6A})
if s.registers.getA() != 0x87 {
t.Errorf("Error in ROR. %v", s.registers)
}
if !s.registers.getFlag(flagC) {
t.Errorf("Error in ROR carry")
}
}

View File

@ -1,5 +1,7 @@
package main
import "fmt"
const (
regA = 0
regX = 1
@ -52,13 +54,12 @@ func (r *registers) setPC(v uint16) {
func (r *registers) getFlagBit(i uint8) uint8 {
if r.getFlag(i) {
return 1
} else {
return 0
}
return 0
}
func (r *registers) getFlag(i uint8) bool {
return (r.data[regP] & i ) != 0
return (r.data[regP] & i) != 0
}
func (r *registers) setFlag(i uint8) {
@ -81,3 +82,8 @@ func (r *registers) updateFlagZN(t uint8) {
r.updateFlag(flagZ, t == 0)
r.updateFlag(flagN, t >= (1<<7))
}
func (r registers) String() string {
return fmt.Sprintf("A: %#02x, X: %#02x, Y: %#02x, SP: %#02x, PC: %#04x, P: %#02x, (NV-BDIZC): %08b",
r.getA(), r.getX(), r.getY(), r.getSP(), r.getPC(), r.getP(), r.getP())
}