Module: Badline::InstructionSet::Illegal

Included in:
Badline::InstructionSet
Defined in:
lib/badline/instruction_set/illegal.rb

Overview

Illegal opcodes

Instance Method Summary collapse

Instance Method Details

#alr(_addr, value) ⇒ Object

Combination of AND and LSR.

Opcodes:

$4B - immediate - 2 cycles


11
12
13
14
15
16
# File 'lib/badline/instruction_set/illegal.rb', line 11

def alr(_addr, value)
  @a &= resolve(value)
  status.carry = @a[0]
  @a = (@a >> 1) & 0xff
  update_number_flags(@a)
end

#anc(addr, value) ⇒ Object

Combination of AND where carry is set to bit 7 of result.

Opcodes:

$0B, $2B - immediate - 2 cycles


22
23
24
25
# File 'lib/badline/instruction_set/illegal.rb', line 22

def anc(addr, value)
  self.and(addr, value)
  status.carry = status.negative
end

#ane(_addr, value) ⇒ Object

Unstable instruction. AND’s value with A|magic_const and X. Magic constant varies by CPU.

Opcodes:

$8B - immediate - 2 cycles


32
33
34
35
36
# File 'lib/badline/instruction_set/illegal.rb', line 32

def ane(_addr, value)
  magic_const = 0xee
  @a = (a | magic_const) & x & resolve(value)
  update_number_flags(@a)
end

#arr(_addr, value) ⇒ Object

Combination of AND and ROR.

Opcodes:

$6B - immediate - 2 cycles


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/badline/instruction_set/illegal.rb', line 42

def arr(_addr, value)
  tmp = a & resolve(value)
  result = (tmp >> 1) | (status.carry? ? 0x80 : 0)
  status.zero = result.zero?
  status.negative = status.carry

  if status.decimal?
    status.overflow = (result ^ tmp).anybits?(0x40)

    # Low nibble
    result = (result & 0xf0) | ((result + 0x06) & 0x0f) if ((tmp & 0x0f) + (tmp & 0x01)) > 0x05

    # High nibble + carry
    if ((tmp & 0xf0) + (tmp & 0x10)) > 0x50
      result = (result & 0x0f) | ((result + 0x60) & 0xf0)
      status.carry = true
    else
      status.carry = false
    end
  else
    status.carry = tmp[7] == 1
    status.overflow = tmp[7] ^ tmp[6]
  end

  @a = result
end

#dcp(addr, value) ⇒ Object

Combination of DEC and CMP operations.

Opcodes:

$C3 - indirect_x - 8 cycles
$C7 - zeropage   - 5 cycles
$CF - absolute   - 6 cycles
$D3 - indirect_y - 8 cycles
$D7 - zeropage_x - 6 cycles
$DB - absolute_y - 7 cycles
$DF - absolute_x - 7 cycles


79
80
81
# File 'lib/badline/instruction_set/illegal.rb', line 79

def dcp(addr, value)
  cmp(addr, dec(addr, value))
end

#isc(addr, value) ⇒ Object

Combination of INC and SBC operations.

Opcodes:

$E3 - indirect_x - 8 cycles
$E7 - zeropage   - 5 cycles
$EF - absolute   - 6 cycles
$F3 - indirect_y - 8 cycles
$F7 - zeropage_x - 6 cycles
$FB - absolute_y - 7 cycles
$FF - absolute_x - 7 cycles


93
94
95
# File 'lib/badline/instruction_set/illegal.rb', line 93

def isc(addr, value)
  sbc(addr, inc(addr, value))
end

#jam(_addr, _value) ⇒ Object

Freezes the CPU by forcing an infinite loop.

Opcodes:

$02, $12, $22, $32, $42, $52, $62, $72, $92, $B2, $D2, $F2


101
102
103
104
105
106
# File 'lib/badline/instruction_set/illegal.rb', line 101

def jam(_addr, _value)
  # TODO: Handle jam
  # It is possible to implement with loop { cycle }, but makes
  # testing problematic.
  10.times { cycle }
end

#las(_addr, value) ⇒ Object

Loads A and S with value AND stack pointer.

Opcodes:

$BB - absolute_y - 4 cycles


112
113
114
115
# File 'lib/badline/instruction_set/illegal.rb', line 112

def las(_addr, value)
  @a = @x = @stack_pointer = resolve(value) & stack_pointer
  update_number_flags(@a)
end

#lax(_addr, value) ⇒ Object

Combination of LDA and LDX with same value.

Opcodes:

$A3 - indirect_x - 6 cycles
$A7 - zeropage   - 3 cycles
$AF - absolute   - 4 cycles
$B3 - indirect_y - 5+ cycles
$B7 - zeropage_y - 4 cycles
$BF - absolute_y - 4+ cycles


126
127
128
129
130
# File 'lib/badline/instruction_set/illegal.rb', line 126

def lax(_addr, value)
  @a = @x = resolve(value)

  update_number_flags(@a)
end

#lxa(_addr, value) ⇒ Object

Unstable immediate form of LAX. Loads A and X with (A | magic_const) AND value. Magic constant varies by CPU.

Opcodes:

$AB - immediate - 2 cycles


137
138
139
140
141
# File 'lib/badline/instruction_set/illegal.rb', line 137

def lxa(_addr, value)
  magic_const = 0xee
  @a = @x = (a | magic_const) & resolve(value)
  update_number_flags(@a)
end

#nop_nocycle(_addr, _value) ⇒ Object

Special no-operation instruction that does not consume a CPU cycle, unlike the standard NOP. Used by some illegal opcodes.

Opcodes:

$80, $82, $89, $C2, $E2 - immediate - 2 cycles


148
# File 'lib/badline/instruction_set/illegal.rb', line 148

def nop_nocycle(_addr, _value); end

#rla(addr, value) ⇒ Object

Combination of ROL and AND operations.

Opcodes:

$23 - indirect_x - 8 cycles
$27 - zeropage   - 5 cycles
$2F - absolute   - 6 cycles
$33 - indirect_y - 8 cycles
$37 - zeropage_x - 6 cycles
$3B - absolute_y - 7 cycles
$3F - absolute_x - 7 cycles


160
161
162
# File 'lib/badline/instruction_set/illegal.rb', line 160

def rla(addr, value)
  self.and(addr, rol(addr, value))
end

#rra(addr, value) ⇒ Object

Combination of ROR and ADC operations.

Opcodes:

$63 - indirect_x - 8 cycles
$67 - zeropage   - 5 cycles
$6F - absolute   - 6 cycles
$73 - indirect_y - 8 cycles
$77 - zeropage_x - 6 cycles
$7B - absolute_y - 7 cycles
$7F - absolute_x - 7 cycles


174
175
176
# File 'lib/badline/instruction_set/illegal.rb', line 174

def rra(addr, value)
  adc(addr, ror(addr, value))
end

#sax(addr, _value) ⇒ Object

Store A AND X.

Opcodes:

$83 - indirect_x - 6 cycles
$87 - zeropage   - 3 cycles
$8F - absolute   - 4 cycles
$97 - zeropage_y - 4 cycles


185
186
187
# File 'lib/badline/instruction_set/illegal.rb', line 185

def sax(addr, _value)
  write_byte(addr, @a & @x)
end

#sbx(_addr, value) ⇒ Object

AND X register with accumulator and subtract value.

Opcodes:

$CB - immediate - 2 cycles


193
194
195
196
197
198
199
# File 'lib/badline/instruction_set/illegal.rb', line 193

def sbx(_addr, value)
  v = resolve(value)
  result = (@x & @a) - v
  status.carry = result >= 0
  @x = result & 0xff
  update_number_flags(@x)
end

#sha(addr, _value) ⇒ Object

Stores A AND X AND (high byte of base address + 1) at addr.

Opcodes:

$93 - indirect_y - 6 cycles
$9F - absolute_y - 5 cycles


206
207
208
# File 'lib/badline/instruction_set/illegal.rb', line 206

def sha(addr, _value)
  store_high_and(a & x, addr)
end

#shx(addr, _value) ⇒ Object

Stores X AND (high byte of base address + 1) at addr.

Opcodes:

$9E - absolute_y - 5 cycles


214
215
216
# File 'lib/badline/instruction_set/illegal.rb', line 214

def shx(addr, _value)
  store_high_and(x, addr)
end

#shy(addr, _value) ⇒ Object

Stores Y AND (high byte of base address + 1) at addr.

Opcodes:

$9C - absolute_x - 5 cycles


222
223
224
# File 'lib/badline/instruction_set/illegal.rb', line 222

def shy(addr, _value)
  store_high_and(y, addr)
end

#slo(addr, value) ⇒ Object

Combination of ASL and ORA operations.

Opcodes:

$03 - indirect_x - 8 cycles
$07 - zeropage   - 5 cycles
$0F - absolute   - 6 cycles
$13 - indirect_y - 8 cycles
$17 - zeropage_x - 6 cycles
$1B - absolute_y - 7 cycles
$1F - absolute_x - 7 cycles


236
237
238
# File 'lib/badline/instruction_set/illegal.rb', line 236

def slo(addr, value)
  ora(addr, asl(addr, value))
end

#sre(addr, value) ⇒ Object

Combination of LSR and EOR operations.

Opcodes:

$43 - indirect_x - 8 cycles
$47 - zeropage   - 5 cycles
$4F - absolute   - 6 cycles
$53 - indirect_y - 8 cycles
$57 - zeropage_x - 6 cycles
$5B - absolute_y - 7 cycles
$5F - absolute_x - 7 cycles


250
251
252
# File 'lib/badline/instruction_set/illegal.rb', line 250

def sre(addr, value)
  eor(addr, lsr(addr, value))
end

#tas(addr, _value) ⇒ Object

Stores A AND X in SP, then stores SP AND (high byte of base + 1) at addr.

Opcodes:

$9B - absolute_y - 5 cycles


259
260
261
262
# File 'lib/badline/instruction_set/illegal.rb', line 259

def tas(addr, _value)
  @stack_pointer = @a & @x
  store_high_and(stack_pointer, addr)
end