Skip to content

Commit

Permalink
Move the underlying Cpu ops methods to their own file.
Browse files Browse the repository at this point in the history
  • Loading branch information
hainesr committed Oct 24, 2020
1 parent 8c90997 commit 8172279
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 91 deletions.
6 changes: 4 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
91 changes: 2 additions & 89 deletions lib/mos6502/cpu_instructions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
100 changes: 100 additions & 0 deletions lib/mos6502/cpu_ops.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 8172279

Please sign in to comment.