From 9b0dac5ac8662767446567b90abc65f8f8657f37 Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Mon, 28 Jan 2019 23:10:23 +0100 Subject: [PATCH] Fixed ROL A, added ROR --- execute.go | 36 ++++++++++++++++++++++++++---------- execute_test.go | 27 +++++++++++++++++++++++++-- registers.go | 12 +++++++++--- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/execute.go b/execute.go index 2074277..fe2e303 100644 --- a/execute.go +++ b/execute.go @@ -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)}, diff --git a/execute_test.go b/execute_test.go index 70ce222..1be46e4 100644 --- a/execute_test.go +++ b/execute_test.go @@ -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") + } } diff --git a/registers.go b/registers.go index 0018daa..a589176 100644 --- a/registers.go +++ b/registers.go @@ -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()) +}