From 817227976b86854fc693ed1e63dfe2cd4289289a Mon Sep 17 00:00:00 2001 From: Robert Haines Date: Sat, 24 Oct 2020 15:03:13 +0100 Subject: [PATCH] Move the underlying Cpu ops methods to their own file. --- .rubocop.yml | 6 +- lib/mos6502/cpu_instructions.rb | 91 +---------------------------- lib/mos6502/cpu_ops.rb | 100 ++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 91 deletions(-) create mode 100644 lib/mos6502/cpu_ops.rb diff --git a/.rubocop.yml b/.rubocop.yml index 9b4c5e3..5e4b64e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,11 +5,12 @@ AllCops: NewCops: enable # Set a slightly bigger default, and ignore ABC failures in the tests. -# Also ignore in the CPU instructions file, which is unavoidably big. +# Also ignore in the CPU instructions files, which are unavoidably big. Metrics/AbcSize: Max: 25 Exclude: - 'lib/mos6502/cpu_instructions.rb' + - 'lib/mos6502/cpu_ops.rb' - 'test/**/*.rb' # Ignore block length failures in the tests. @@ -33,10 +34,11 @@ Metrics/CyclomaticComplexity: - 'lib/mos6502/cpu_instructions.rb' # Ignore method length failures in the tests. -# Also ignore in the CPU instructions file, which is unavoidably big. +# Also ignore in the CPU instructions files, which are unavoidably big. Metrics/MethodLength: Exclude: - 'lib/mos6502/cpu_instructions.rb' + - 'lib/mos6502/cpu_ops.rb' - 'test/**/*.rb' # Ignore module length failures in the tests. diff --git a/lib/mos6502/cpu_instructions.rb b/lib/mos6502/cpu_instructions.rb index cb34a0e..8a7b19f 100644 --- a/lib/mos6502/cpu_instructions.rb +++ b/lib/mos6502/cpu_instructions.rb @@ -4,99 +4,12 @@ # # Licensed under the BSD License. See LICENCE for details. +require_relative 'cpu_ops' + module Mos6502 class Cpu private - def branch(offset) - if offset > 0x7f - @pc - (0x100 - offset) - else - @pc + offset - end - end - - def compare(register, value) - @status.carry = register >= value - set_nz_flags(register - value) - end - - def adc(value) - carry = @status.carry? ? 1 : 0 - - if @status.decimal_mode? - result = (@a & 0x0f) + (value & 0x0f) + carry - result = 0x10 | ((result + 0x06) & 0x0f) if result >= 0x0a - result += (@a & 0xf0) + (value & 0xf0) - - if result >= 0xa0 - result += 0x60 - @status.carry = true - @status.overflow = ((@a ^ value) & 0x80).zero? && (result >= 0x0180) - else - @status.carry = false - @status.overflow = !((@a ^ value) & 0x80).zero? && (result < 0x80) - end - else - result = @a + value + carry - @status.overflow = - (((@a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (result >> 8) - @status.carry = result > 0xff - end - - @a = result & 0xff - set_nz_flags(@a) - end - - def sbc(value) - if @status.decimal_mode? - carry = @status.carry? ? 1 : 0 - ones = 0x0f + (@a & 0x0f) - (value & 0x0f) + carry - tens = 0xf0 + (@a & 0xf0) - (value & 0xf0) - - if ones < 0x10 - ones -= 6 - else - tens += 0x10 - ones -= 0x10 - end - - if tens < 0x100 - tens -= 0x60 - @status.carry = false - @status.overflow = !((@a ^ value) & 0x80).zero? && (tens < 0x80) - else - @status.carry = true - @status.overflow = !((@a ^ value) & 0x80).zero? && (tens < 0x0180) - end - - @a = (ones + tens) & 0xff - set_nz_flags(@a) - else - adc(value ^ 0xff) - end - end - - def asl(value) - set_carry(value, 7) - value = value << 1 - set_nz_flags(value) - value - end - - def lsr(value) - set_carry(value, 0) - value = value >> 1 - set_nz_flags(value) - value - end - - def bit(value) - @status.zero = (@a & value).zero? - @status.overflow = value & 0x40 - @status.negative = value & 0x80 - end - def instructions { # BRK diff --git a/lib/mos6502/cpu_ops.rb b/lib/mos6502/cpu_ops.rb new file mode 100644 index 0000000..68b43d1 --- /dev/null +++ b/lib/mos6502/cpu_ops.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +# Copyright (c) 2020, Robert Haines. +# +# Licensed under the BSD License. See LICENCE for details. + +module Mos6502 + class Cpu + private + + def adc(value) + carry = @status.carry? ? 1 : 0 + + if @status.decimal_mode? + result = (@a & 0x0f) + (value & 0x0f) + carry + result = 0x10 | ((result + 0x06) & 0x0f) if result >= 0x0a + result += (@a & 0xf0) + (value & 0xf0) + + if result >= 0xa0 + result += 0x60 + @status.carry = true + @status.overflow = ((@a ^ value) & 0x80).zero? && (result >= 0x0180) + else + @status.carry = false + @status.overflow = !((@a ^ value) & 0x80).zero? && (result < 0x80) + end + else + result = @a + value + carry + @status.overflow = + (((@a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (result >> 8) + @status.carry = result > 0xff + end + + @a = result & 0xff + set_nz_flags(@a) + end + + def asl(value) + set_carry(value, 7) + value = value << 1 + set_nz_flags(value) + value + end + + def bit(value) + @status.zero = (@a & value).zero? + @status.overflow = value & 0x40 + @status.negative = value & 0x80 + end + + def branch(offset) + if offset > 0x7f + @pc - (0x100 - offset) + else + @pc + offset + end + end + + def compare(register, value) + @status.carry = register >= value + set_nz_flags(register - value) + end + + def lsr(value) + set_carry(value, 0) + value = value >> 1 + set_nz_flags(value) + value + end + + def sbc(value) + if @status.decimal_mode? + carry = @status.carry? ? 1 : 0 + ones = 0x0f + (@a & 0x0f) - (value & 0x0f) + carry + tens = 0xf0 + (@a & 0xf0) - (value & 0xf0) + + if ones < 0x10 + ones -= 6 + else + tens += 0x10 + ones -= 0x10 + end + + if tens < 0x100 + tens -= 0x60 + @status.carry = false + @status.overflow = !((@a ^ value) & 0x80).zero? && (tens < 0x80) + else + @status.carry = true + @status.overflow = !((@a ^ value) & 0x80).zero? && (tens < 0x0180) + end + + @a = (ones + tens) & 0xff + set_nz_flags(@a) + else + adc(value ^ 0xff) + end + end + end +end